Skip to content

Commit 655ef63

Browse files
noctuellesherbertx
authored andcommitted
crypto: talitos - fix SEC1 32k ahash request limitation
Since commit c662b04 ("crypto: af_alg/hash: Support MSG_SPLICE_PAGES"), the crypto core may pass large scatterlists spanning multiple pages to drivers supporting ahash operations. As a result, a driver can now receive large ahash requests. The SEC1 engine has a limitation where a single descriptor cannot process more than 32k of data. The current implementation attempts to handle the entire request within a single descriptor, which leads to failures raised by the driver: "length exceeds h/w max limit" Address this limitation by splitting large ahash requests into multiple descriptors, each respecting the 32k hardware limit. This allows processing arbitrarily large requests. Cc: stable@vger.kernel.org Fixes: c662b04 ("crypto: af_alg/hash: Support MSG_SPLICE_PAGES") Signed-off-by: Paul Louvel <paul.louvel@bootlin.com> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
1 parent 01d798e commit 655ef63

1 file changed

Lines changed: 147 additions & 69 deletions

File tree

drivers/crypto/talitos.c

Lines changed: 147 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
* All rights reserved.
1313
*/
1414

15+
#include <linux/workqueue.h>
1516
#include <linux/kernel.h>
1617
#include <linux/module.h>
1718
#include <linux/mod_devicetable.h>
@@ -870,10 +871,18 @@ struct talitos_ahash_req_ctx {
870871
unsigned int swinit;
871872
unsigned int first;
872873
unsigned int last;
874+
unsigned int last_request;
873875
unsigned int to_hash_later;
874876
unsigned int nbuf;
875877
struct scatterlist bufsl[2];
876878
struct scatterlist *psrc;
879+
880+
struct scatterlist request_bufsl[2];
881+
struct ahash_request *areq;
882+
struct scatterlist *request_sl;
883+
unsigned int remaining_ahash_request_bytes;
884+
unsigned int current_ahash_request_bytes;
885+
struct work_struct sec1_ahash_process_remaining;
877886
};
878887

879888
struct talitos_export_state {
@@ -1759,7 +1768,20 @@ static void ahash_done(struct device *dev,
17591768

17601769
kfree(edesc);
17611770

1762-
ahash_request_complete(areq, err);
1771+
if (err) {
1772+
ahash_request_complete(areq, err);
1773+
return;
1774+
}
1775+
1776+
req_ctx->remaining_ahash_request_bytes -=
1777+
req_ctx->current_ahash_request_bytes;
1778+
1779+
if (!req_ctx->remaining_ahash_request_bytes) {
1780+
ahash_request_complete(areq, 0);
1781+
return;
1782+
}
1783+
1784+
schedule_work(&req_ctx->sec1_ahash_process_remaining);
17631785
}
17641786

17651787
/*
@@ -1925,60 +1947,7 @@ static struct talitos_edesc *ahash_edesc_alloc(struct ahash_request *areq,
19251947
nbytes, 0, 0, 0, areq->base.flags, false);
19261948
}
19271949

1928-
static int ahash_init(struct ahash_request *areq)
1929-
{
1930-
struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq);
1931-
struct talitos_ctx *ctx = crypto_ahash_ctx(tfm);
1932-
struct device *dev = ctx->dev;
1933-
struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
1934-
unsigned int size;
1935-
dma_addr_t dma;
1936-
1937-
/* Initialize the context */
1938-
req_ctx->buf_idx = 0;
1939-
req_ctx->nbuf = 0;
1940-
req_ctx->first = 1; /* first indicates h/w must init its context */
1941-
req_ctx->swinit = 0; /* assume h/w init of context */
1942-
size = (crypto_ahash_digestsize(tfm) <= SHA256_DIGEST_SIZE)
1943-
? TALITOS_MDEU_CONTEXT_SIZE_MD5_SHA1_SHA256
1944-
: TALITOS_MDEU_CONTEXT_SIZE_SHA384_SHA512;
1945-
req_ctx->hw_context_size = size;
1946-
1947-
dma = dma_map_single(dev, req_ctx->hw_context, req_ctx->hw_context_size,
1948-
DMA_TO_DEVICE);
1949-
dma_unmap_single(dev, dma, req_ctx->hw_context_size, DMA_TO_DEVICE);
1950-
1951-
return 0;
1952-
}
1953-
1954-
/*
1955-
* on h/w without explicit sha224 support, we initialize h/w context
1956-
* manually with sha224 constants, and tell it to run sha256.
1957-
*/
1958-
static int ahash_init_sha224_swinit(struct ahash_request *areq)
1959-
{
1960-
struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
1961-
1962-
req_ctx->hw_context[0] = SHA224_H0;
1963-
req_ctx->hw_context[1] = SHA224_H1;
1964-
req_ctx->hw_context[2] = SHA224_H2;
1965-
req_ctx->hw_context[3] = SHA224_H3;
1966-
req_ctx->hw_context[4] = SHA224_H4;
1967-
req_ctx->hw_context[5] = SHA224_H5;
1968-
req_ctx->hw_context[6] = SHA224_H6;
1969-
req_ctx->hw_context[7] = SHA224_H7;
1970-
1971-
/* init 64-bit count */
1972-
req_ctx->hw_context[8] = 0;
1973-
req_ctx->hw_context[9] = 0;
1974-
1975-
ahash_init(areq);
1976-
req_ctx->swinit = 1;/* prevent h/w initting context with sha256 values*/
1977-
1978-
return 0;
1979-
}
1980-
1981-
static int ahash_process_req(struct ahash_request *areq, unsigned int nbytes)
1950+
static int ahash_process_req_one(struct ahash_request *areq, unsigned int nbytes)
19821951
{
19831952
struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq);
19841953
struct talitos_ctx *ctx = crypto_ahash_ctx(tfm);
@@ -1997,12 +1966,12 @@ static int ahash_process_req(struct ahash_request *areq, unsigned int nbytes)
19971966

19981967
if (!req_ctx->last && (nbytes + req_ctx->nbuf <= blocksize)) {
19991968
/* Buffer up to one whole block */
2000-
nents = sg_nents_for_len(areq->src, nbytes);
1969+
nents = sg_nents_for_len(req_ctx->request_sl, nbytes);
20011970
if (nents < 0) {
20021971
dev_err(dev, "Invalid number of src SG.\n");
20031972
return nents;
20041973
}
2005-
sg_copy_to_buffer(areq->src, nents,
1974+
sg_copy_to_buffer(req_ctx->request_sl, nents,
20061975
ctx_buf + req_ctx->nbuf, nbytes);
20071976
req_ctx->nbuf += nbytes;
20081977
return 0;
@@ -2029,7 +1998,7 @@ static int ahash_process_req(struct ahash_request *areq, unsigned int nbytes)
20291998
sg_init_table(req_ctx->bufsl, nsg);
20301999
sg_set_buf(req_ctx->bufsl, ctx_buf, req_ctx->nbuf);
20312000
if (nsg > 1)
2032-
sg_chain(req_ctx->bufsl, 2, areq->src);
2001+
sg_chain(req_ctx->bufsl, 2, req_ctx->request_sl);
20332002
req_ctx->psrc = req_ctx->bufsl;
20342003
} else if (is_sec1 && req_ctx->nbuf && req_ctx->nbuf < blocksize) {
20352004
int offset;
@@ -2038,34 +2007,34 @@ static int ahash_process_req(struct ahash_request *areq, unsigned int nbytes)
20382007
offset = blocksize - req_ctx->nbuf;
20392008
else
20402009
offset = nbytes_to_hash - req_ctx->nbuf;
2041-
nents = sg_nents_for_len(areq->src, offset);
2010+
nents = sg_nents_for_len(req_ctx->request_sl, offset);
20422011
if (nents < 0) {
20432012
dev_err(dev, "Invalid number of src SG.\n");
20442013
return nents;
20452014
}
2046-
sg_copy_to_buffer(areq->src, nents,
2015+
sg_copy_to_buffer(req_ctx->request_sl, nents,
20472016
ctx_buf + req_ctx->nbuf, offset);
20482017
req_ctx->nbuf += offset;
2049-
req_ctx->psrc = scatterwalk_ffwd(req_ctx->bufsl, areq->src,
2018+
req_ctx->psrc = scatterwalk_ffwd(req_ctx->bufsl, req_ctx->request_sl,
20502019
offset);
20512020
} else
2052-
req_ctx->psrc = areq->src;
2021+
req_ctx->psrc = req_ctx->request_sl;
20532022

20542023
if (to_hash_later) {
2055-
nents = sg_nents_for_len(areq->src, nbytes);
2024+
nents = sg_nents_for_len(req_ctx->request_sl, nbytes);
20562025
if (nents < 0) {
20572026
dev_err(dev, "Invalid number of src SG.\n");
20582027
return nents;
20592028
}
2060-
sg_pcopy_to_buffer(areq->src, nents,
2029+
sg_pcopy_to_buffer(req_ctx->request_sl, nents,
20612030
req_ctx->buf[(req_ctx->buf_idx + 1) & 1],
20622031
to_hash_later,
20632032
nbytes - to_hash_later);
20642033
}
20652034
req_ctx->to_hash_later = to_hash_later;
20662035

20672036
/* Allocate extended descriptor */
2068-
edesc = ahash_edesc_alloc(areq, nbytes_to_hash);
2037+
edesc = ahash_edesc_alloc(req_ctx->areq, nbytes_to_hash);
20692038
if (IS_ERR(edesc))
20702039
return PTR_ERR(edesc);
20712040

@@ -2087,14 +2056,123 @@ static int ahash_process_req(struct ahash_request *areq, unsigned int nbytes)
20872056
if (ctx->keylen && (req_ctx->first || req_ctx->last))
20882057
edesc->desc.hdr |= DESC_HDR_MODE0_MDEU_HMAC;
20892058

2090-
return common_nonsnoop_hash(edesc, areq, nbytes_to_hash, ahash_done);
2059+
return common_nonsnoop_hash(edesc, req_ctx->areq, nbytes_to_hash, ahash_done);
20912060
}
20922061

2093-
static int ahash_update(struct ahash_request *areq)
2062+
static void sec1_ahash_process_remaining(struct work_struct *work)
2063+
{
2064+
struct talitos_ahash_req_ctx *req_ctx =
2065+
container_of(work, struct talitos_ahash_req_ctx,
2066+
sec1_ahash_process_remaining);
2067+
int err = 0;
2068+
2069+
req_ctx->request_sl = scatterwalk_ffwd(req_ctx->request_bufsl,
2070+
req_ctx->request_sl, TALITOS1_MAX_DATA_LEN);
2071+
2072+
if (req_ctx->remaining_ahash_request_bytes > TALITOS1_MAX_DATA_LEN)
2073+
req_ctx->current_ahash_request_bytes = TALITOS1_MAX_DATA_LEN;
2074+
else {
2075+
req_ctx->current_ahash_request_bytes =
2076+
req_ctx->remaining_ahash_request_bytes;
2077+
2078+
if (req_ctx->last_request)
2079+
req_ctx->last = 1;
2080+
}
2081+
2082+
err = ahash_process_req_one(req_ctx->areq,
2083+
req_ctx->current_ahash_request_bytes);
2084+
2085+
if (err != -EINPROGRESS)
2086+
ahash_request_complete(req_ctx->areq, err);
2087+
}
2088+
2089+
static int ahash_process_req(struct ahash_request *areq, unsigned int nbytes)
2090+
{
2091+
struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq);
2092+
struct talitos_ctx *ctx = crypto_ahash_ctx(tfm);
2093+
struct device *dev = ctx->dev;
2094+
struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
2095+
struct talitos_private *priv = dev_get_drvdata(dev);
2096+
bool is_sec1 = has_ftr_sec1(priv);
2097+
2098+
req_ctx->areq = areq;
2099+
req_ctx->request_sl = areq->src;
2100+
req_ctx->remaining_ahash_request_bytes = nbytes;
2101+
2102+
if (is_sec1) {
2103+
if (nbytes > TALITOS1_MAX_DATA_LEN)
2104+
nbytes = TALITOS1_MAX_DATA_LEN;
2105+
else if (req_ctx->last_request)
2106+
req_ctx->last = 1;
2107+
}
2108+
2109+
req_ctx->current_ahash_request_bytes = nbytes;
2110+
2111+
return ahash_process_req_one(req_ctx->areq,
2112+
req_ctx->current_ahash_request_bytes);
2113+
}
2114+
2115+
static int ahash_init(struct ahash_request *areq)
20942116
{
2117+
struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq);
2118+
struct talitos_ctx *ctx = crypto_ahash_ctx(tfm);
2119+
struct device *dev = ctx->dev;
20952120
struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
2121+
unsigned int size;
2122+
dma_addr_t dma;
20962123

2124+
/* Initialize the context */
2125+
req_ctx->buf_idx = 0;
2126+
req_ctx->nbuf = 0;
2127+
req_ctx->first = 1; /* first indicates h/w must init its context */
2128+
req_ctx->swinit = 0; /* assume h/w init of context */
2129+
size = (crypto_ahash_digestsize(tfm) <= SHA256_DIGEST_SIZE)
2130+
? TALITOS_MDEU_CONTEXT_SIZE_MD5_SHA1_SHA256
2131+
: TALITOS_MDEU_CONTEXT_SIZE_SHA384_SHA512;
2132+
req_ctx->hw_context_size = size;
2133+
req_ctx->last_request = 0;
20972134
req_ctx->last = 0;
2135+
INIT_WORK(&req_ctx->sec1_ahash_process_remaining, sec1_ahash_process_remaining);
2136+
2137+
dma = dma_map_single(dev, req_ctx->hw_context, req_ctx->hw_context_size,
2138+
DMA_TO_DEVICE);
2139+
dma_unmap_single(dev, dma, req_ctx->hw_context_size, DMA_TO_DEVICE);
2140+
2141+
return 0;
2142+
}
2143+
2144+
/*
2145+
* on h/w without explicit sha224 support, we initialize h/w context
2146+
* manually with sha224 constants, and tell it to run sha256.
2147+
*/
2148+
static int ahash_init_sha224_swinit(struct ahash_request *areq)
2149+
{
2150+
struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
2151+
2152+
req_ctx->hw_context[0] = SHA224_H0;
2153+
req_ctx->hw_context[1] = SHA224_H1;
2154+
req_ctx->hw_context[2] = SHA224_H2;
2155+
req_ctx->hw_context[3] = SHA224_H3;
2156+
req_ctx->hw_context[4] = SHA224_H4;
2157+
req_ctx->hw_context[5] = SHA224_H5;
2158+
req_ctx->hw_context[6] = SHA224_H6;
2159+
req_ctx->hw_context[7] = SHA224_H7;
2160+
2161+
/* init 64-bit count */
2162+
req_ctx->hw_context[8] = 0;
2163+
req_ctx->hw_context[9] = 0;
2164+
2165+
ahash_init(areq);
2166+
req_ctx->swinit = 1;/* prevent h/w initting context with sha256 values*/
2167+
2168+
return 0;
2169+
}
2170+
2171+
static int ahash_update(struct ahash_request *areq)
2172+
{
2173+
struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
2174+
2175+
req_ctx->last_request = 0;
20982176

20992177
return ahash_process_req(areq, areq->nbytes);
21002178
}
@@ -2103,7 +2181,7 @@ static int ahash_final(struct ahash_request *areq)
21032181
{
21042182
struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
21052183

2106-
req_ctx->last = 1;
2184+
req_ctx->last_request = 1;
21072185

21082186
return ahash_process_req(areq, 0);
21092187
}
@@ -2112,7 +2190,7 @@ static int ahash_finup(struct ahash_request *areq)
21122190
{
21132191
struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
21142192

2115-
req_ctx->last = 1;
2193+
req_ctx->last_request = 1;
21162194

21172195
return ahash_process_req(areq, areq->nbytes);
21182196
}

0 commit comments

Comments
 (0)