@@ -58,6 +58,9 @@ module_param(fuzz_iterations, uint, 0644);
58
58
MODULE_PARM_DESC (fuzz_iterations , "number of fuzz test iterations" );
59
59
#endif
60
60
61
+ /* Multibuffer is unlimited. Set arbitrary limit for testing. */
62
+ #define MAX_MB_MSGS 16
63
+
61
64
#ifdef CONFIG_CRYPTO_MANAGER_DISABLE_TESTS
62
65
63
66
/* a perfect nop */
@@ -299,6 +302,13 @@ struct test_sg_division {
299
302
* @key_offset_relative_to_alignmask: if true, add the algorithm's alignmask to
300
303
* the @key_offset
301
304
* @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
302
312
* @nosimd: execute with SIMD disabled? Requires !CRYPTO_TFM_REQ_MAY_SLEEP.
303
313
* This applies to the parts of the operation that aren't controlled
304
314
* individually by @nosimd_setkey or @src_divs[].nosimd.
@@ -318,6 +328,11 @@ struct testvec_config {
318
328
enum finalization_type finalization_type ;
319
329
bool nosimd ;
320
330
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 ];
321
336
};
322
337
323
338
#define TESTVEC_CONFIG_NAMELEN 192
@@ -557,6 +572,7 @@ struct test_sglist {
557
572
char * bufs [XBUFSIZE ];
558
573
struct scatterlist sgl [XBUFSIZE ];
559
574
struct scatterlist sgl_saved [XBUFSIZE ];
575
+ struct scatterlist full_sgl [XBUFSIZE ];
560
576
struct scatterlist * sgl_ptr ;
561
577
unsigned int nents ;
562
578
};
@@ -670,6 +686,11 @@ static int build_test_sglist(struct test_sglist *tsgl,
670
686
sg_mark_end (& tsgl -> sgl [tsgl -> nents - 1 ]);
671
687
tsgl -> sgl_ptr = tsgl -> sgl ;
672
688
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
+
673
694
return 0 ;
674
695
}
675
696
@@ -1146,6 +1167,27 @@ static void generate_random_testvec_config(struct rnd_state *rng,
1146
1167
break ;
1147
1168
}
1148
1169
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
+
1149
1191
if (!(cfg -> req_flags & CRYPTO_TFM_REQ_MAY_SLEEP )) {
1150
1192
if (prandom_bool (rng )) {
1151
1193
cfg -> nosimd = true;
@@ -1450,6 +1492,7 @@ static int do_ahash_op(int (*op)(struct ahash_request *req),
1450
1492
struct ahash_request * req ,
1451
1493
struct crypto_wait * wait , bool nosimd )
1452
1494
{
1495
+ struct ahash_request * r2 ;
1453
1496
int err ;
1454
1497
1455
1498
if (nosimd )
@@ -1460,7 +1503,15 @@ static int do_ahash_op(int (*op)(struct ahash_request *req),
1460
1503
if (nosimd )
1461
1504
crypto_reenable_simd_for_test ();
1462
1505
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 ;
1464
1515
}
1465
1516
1466
1517
static 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,
1481
1532
return 0 ;
1482
1533
}
1483
1534
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
+
1484
1578
/* Test one hash test vector in one configuration, using the ahash API */
1485
1579
static int test_ahash_vec_cfg (const struct hash_testvec * vec ,
1486
1580
const char * vec_name ,
1487
1581
const struct testvec_config * cfg ,
1488
- struct ahash_request * req ,
1582
+ struct ahash_request * reqs [ MAX_MB_MSGS ] ,
1489
1583
struct test_sglist * tsgl ,
1490
1584
u8 * hashstate )
1491
1585
{
1586
+ struct ahash_request * req = reqs [0 ];
1492
1587
struct crypto_ahash * tfm = crypto_ahash_reqtfm (req );
1493
1588
const unsigned int digestsize = crypto_ahash_digestsize (tfm );
1494
1589
const unsigned int statesize = crypto_ahash_statesize (tfm );
1495
1590
const char * driver = crypto_ahash_driver_name (tfm );
1496
1591
const u32 req_flags = CRYPTO_TFM_REQ_MAY_BACKLOG | cfg -> req_flags ;
1497
1592
const struct test_sg_division * divs [XBUFSIZE ];
1593
+ struct ahash_request * reqi = req ;
1498
1594
DECLARE_CRYPTO_WAIT (wait );
1499
1595
unsigned int i ;
1500
1596
struct scatterlist * pending_sgl ;
1501
1597
unsigned int pending_len ;
1502
1598
u8 result [HASH_MAX_DIGESTSIZE + TESTMGR_POISON_LEN ];
1503
1599
int err ;
1504
1600
1601
+ if (cfg -> multibuffer )
1602
+ reqi = reqs [cfg -> multibuffer_index ];
1603
+
1505
1604
/* Set the key, if specified */
1506
1605
if (vec -> ksize ) {
1507
1606
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,
1531
1630
1532
1631
/* Do the actual hashing */
1533
1632
1534
- testmgr_poison (req -> __ctx , crypto_ahash_reqsize (tfm ));
1633
+ testmgr_poison (reqi -> __ctx , crypto_ahash_reqsize (tfm ));
1535
1634
testmgr_poison (result , digestsize + TESTMGR_POISON_LEN );
1536
1635
1537
1636
if (cfg -> finalization_type == FINALIZATION_TYPE_DIGEST ||
@@ -1540,6 +1639,7 @@ static int test_ahash_vec_cfg(const struct hash_testvec *vec,
1540
1639
ahash_request_set_callback (req , req_flags , crypto_req_done ,
1541
1640
& wait );
1542
1641
ahash_request_set_crypt (req , tsgl -> sgl , result , vec -> psize );
1642
+ setup_ahash_multibuffer (reqs , cfg , tsgl );
1543
1643
err = do_ahash_op (crypto_ahash_digest , req , & wait , cfg -> nosimd );
1544
1644
if (err ) {
1545
1645
if (err == vec -> digest_error )
@@ -1561,6 +1661,7 @@ static int test_ahash_vec_cfg(const struct hash_testvec *vec,
1561
1661
1562
1662
ahash_request_set_callback (req , req_flags , crypto_req_done , & wait );
1563
1663
ahash_request_set_crypt (req , NULL , result , 0 );
1664
+ setup_ahash_multibuffer (reqs , cfg , tsgl );
1564
1665
err = do_ahash_op (crypto_ahash_init , req , & wait , cfg -> nosimd );
1565
1666
err = check_nonfinal_ahash_op ("init" , err , result , digestsize ,
1566
1667
driver , vec_name , cfg );
@@ -1577,6 +1678,7 @@ static int test_ahash_vec_cfg(const struct hash_testvec *vec,
1577
1678
crypto_req_done , & wait );
1578
1679
ahash_request_set_crypt (req , pending_sgl , result ,
1579
1680
pending_len );
1681
+ setup_ahash_multibuffer (reqs , cfg , tsgl );
1580
1682
err = do_ahash_op (crypto_ahash_update , req , & wait ,
1581
1683
divs [i ]-> nosimd );
1582
1684
err = check_nonfinal_ahash_op ("update" , err ,
@@ -1591,7 +1693,7 @@ static int test_ahash_vec_cfg(const struct hash_testvec *vec,
1591
1693
/* Test ->export() and ->import() */
1592
1694
testmgr_poison (hashstate + statesize ,
1593
1695
TESTMGR_POISON_LEN );
1594
- err = crypto_ahash_export (req , hashstate );
1696
+ err = crypto_ahash_export (reqi , hashstate );
1595
1697
err = check_nonfinal_ahash_op ("export" , err ,
1596
1698
result , digestsize ,
1597
1699
driver , vec_name , cfg );
@@ -1604,8 +1706,8 @@ static int test_ahash_vec_cfg(const struct hash_testvec *vec,
1604
1706
return - EOVERFLOW ;
1605
1707
}
1606
1708
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 );
1609
1711
err = check_nonfinal_ahash_op ("import" , err ,
1610
1712
result , digestsize ,
1611
1713
driver , vec_name , cfg );
@@ -1619,6 +1721,7 @@ static int test_ahash_vec_cfg(const struct hash_testvec *vec,
1619
1721
1620
1722
ahash_request_set_callback (req , req_flags , crypto_req_done , & wait );
1621
1723
ahash_request_set_crypt (req , pending_sgl , result , pending_len );
1724
+ setup_ahash_multibuffer (reqs , cfg , tsgl );
1622
1725
if (cfg -> finalization_type == FINALIZATION_TYPE_FINAL ) {
1623
1726
/* finish with update() and final() */
1624
1727
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,
1650
1753
static int test_hash_vec_cfg (const struct hash_testvec * vec ,
1651
1754
const char * vec_name ,
1652
1755
const struct testvec_config * cfg ,
1653
- struct ahash_request * req ,
1756
+ struct ahash_request * reqs [ MAX_MB_MSGS ] ,
1654
1757
struct shash_desc * desc ,
1655
1758
struct test_sglist * tsgl ,
1656
1759
u8 * hashstate )
@@ -1670,11 +1773,12 @@ static int test_hash_vec_cfg(const struct hash_testvec *vec,
1670
1773
return err ;
1671
1774
}
1672
1775
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 );
1674
1777
}
1675
1778
1676
1779
static 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 ,
1678
1782
struct test_sglist * tsgl , u8 * hashstate )
1679
1783
{
1680
1784
char vec_name [16 ];
@@ -1686,7 +1790,7 @@ static int test_hash_vec(const struct hash_testvec *vec, unsigned int vec_num,
1686
1790
for (i = 0 ; i < ARRAY_SIZE (default_hash_testvec_configs ); i ++ ) {
1687
1791
err = test_hash_vec_cfg (vec , vec_name ,
1688
1792
& default_hash_testvec_configs [i ],
1689
- req , desc , tsgl , hashstate );
1793
+ reqs , desc , tsgl , hashstate );
1690
1794
if (err )
1691
1795
return err ;
1692
1796
}
@@ -1703,7 +1807,7 @@ static int test_hash_vec(const struct hash_testvec *vec, unsigned int vec_num,
1703
1807
generate_random_testvec_config (& rng , & cfg , cfgname ,
1704
1808
sizeof (cfgname ));
1705
1809
err = test_hash_vec_cfg (vec , vec_name , & cfg ,
1706
- req , desc , tsgl , hashstate );
1810
+ reqs , desc , tsgl , hashstate );
1707
1811
if (err )
1708
1812
return err ;
1709
1813
cond_resched ();
@@ -1762,11 +1866,12 @@ static void generate_random_hash_testvec(struct rnd_state *rng,
1762
1866
*/
1763
1867
static int test_hash_vs_generic_impl (const char * generic_driver ,
1764
1868
unsigned int maxkeysize ,
1765
- struct ahash_request * req ,
1869
+ struct ahash_request * reqs [ MAX_MB_MSGS ] ,
1766
1870
struct shash_desc * desc ,
1767
1871
struct test_sglist * tsgl ,
1768
1872
u8 * hashstate )
1769
1873
{
1874
+ struct ahash_request * req = reqs [0 ];
1770
1875
struct crypto_ahash * tfm = crypto_ahash_reqtfm (req );
1771
1876
const unsigned int digestsize = crypto_ahash_digestsize (tfm );
1772
1877
const unsigned int blocksize = crypto_ahash_blocksize (tfm );
@@ -1864,7 +1969,7 @@ static int test_hash_vs_generic_impl(const char *generic_driver,
1864
1969
sizeof (cfgname ));
1865
1970
1866
1971
err = test_hash_vec_cfg (& vec , vec_name , cfg ,
1867
- req , desc , tsgl , hashstate );
1972
+ reqs , desc , tsgl , hashstate );
1868
1973
if (err )
1869
1974
goto out ;
1870
1975
cond_resched ();
@@ -1882,7 +1987,7 @@ static int test_hash_vs_generic_impl(const char *generic_driver,
1882
1987
#else /* !CONFIG_CRYPTO_MANAGER_EXTRA_TESTS */
1883
1988
static int test_hash_vs_generic_impl (const char * generic_driver ,
1884
1989
unsigned int maxkeysize ,
1885
- struct ahash_request * req ,
1990
+ struct ahash_request * reqs [ MAX_MB_MSGS ] ,
1886
1991
struct shash_desc * desc ,
1887
1992
struct test_sglist * tsgl ,
1888
1993
u8 * hashstate )
@@ -1929,8 +2034,8 @@ static int __alg_test_hash(const struct hash_testvec *vecs,
1929
2034
u32 type , u32 mask ,
1930
2035
const char * generic_driver , unsigned int maxkeysize )
1931
2036
{
2037
+ struct ahash_request * reqs [MAX_MB_MSGS ] = {};
1932
2038
struct crypto_ahash * atfm = NULL ;
1933
- struct ahash_request * req = NULL ;
1934
2039
struct crypto_shash * stfm = NULL ;
1935
2040
struct shash_desc * desc = NULL ;
1936
2041
struct test_sglist * tsgl = NULL ;
@@ -1954,12 +2059,14 @@ static int __alg_test_hash(const struct hash_testvec *vecs,
1954
2059
}
1955
2060
driver = crypto_ahash_driver_name (atfm );
1956
2061
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
+ }
1963
2070
}
1964
2071
1965
2072
/*
@@ -1995,12 +2102,12 @@ static int __alg_test_hash(const struct hash_testvec *vecs,
1995
2102
if (fips_enabled && vecs [i ].fips_skip )
1996
2103
continue ;
1997
2104
1998
- err = test_hash_vec (& vecs [i ], i , req , desc , tsgl , hashstate );
2105
+ err = test_hash_vec (& vecs [i ], i , reqs , desc , tsgl , hashstate );
1999
2106
if (err )
2000
2107
goto out ;
2001
2108
cond_resched ();
2002
2109
}
2003
- err = test_hash_vs_generic_impl (generic_driver , maxkeysize , req ,
2110
+ err = test_hash_vs_generic_impl (generic_driver , maxkeysize , reqs ,
2004
2111
desc , tsgl , hashstate );
2005
2112
out :
2006
2113
kfree (hashstate );
@@ -2010,7 +2117,12 @@ static int __alg_test_hash(const struct hash_testvec *vecs,
2010
2117
}
2011
2118
kfree (desc );
2012
2119
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
+ }
2014
2126
crypto_free_ahash (atfm );
2015
2127
return err ;
2016
2128
}
0 commit comments