summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHerbert Xu <herbert@gondor.apana.org.au>2025-03-08 20:45:25 +0800
committerHerbert Xu <herbert@gondor.apana.org.au>2025-03-15 16:21:22 +0800
commitdb873be6f0549597f92c72986b1939643a7f9a75 (patch)
tree49378fa9f942e756cf49ea22dd571c425d32324e
parent131bdceca1f0a2d9381270dc40f898458e5e184b (diff)
crypto: skcipher - Eliminate duplicate virt.addr field
Reuse the addr field from struct scatter_walk for skcipher_walk. Keep the existing virt.addr fields but make them const for the user to access the mapped address. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
-rw-r--r--crypto/skcipher.c29
-rw-r--r--include/crypto/algapi.h5
-rw-r--r--include/crypto/internal/skcipher.h26
3 files changed, 36 insertions, 24 deletions
diff --git a/crypto/skcipher.c b/crypto/skcipher.c
index 0c6911154241..ab5d852febcd 100644
--- a/crypto/skcipher.c
+++ b/crypto/skcipher.c
@@ -43,14 +43,12 @@ static inline void skcipher_map_src(struct skcipher_walk *walk)
{
/* XXX */
walk->in.__addr = scatterwalk_map(&walk->in);
- walk->src.virt.addr = walk->in.addr;
}
static inline void skcipher_map_dst(struct skcipher_walk *walk)
{
/* XXX */
walk->out.__addr = scatterwalk_map(&walk->out);
- walk->dst.virt.addr = walk->out.addr;
}
static inline gfp_t skcipher_walk_gfp(struct skcipher_walk *walk)
@@ -100,8 +98,7 @@ int skcipher_walk_done(struct skcipher_walk *walk, int res)
SKCIPHER_WALK_DIFF)))) {
scatterwalk_advance(&walk->in, n);
} else if (walk->flags & SKCIPHER_WALK_DIFF) {
- scatterwalk_unmap(walk->src.virt.addr);
- scatterwalk_advance(&walk->in, n);
+ scatterwalk_done_src(&walk->in, n);
} else if (walk->flags & SKCIPHER_WALK_COPY) {
scatterwalk_advance(&walk->in, n);
skcipher_map_dst(walk);
@@ -116,11 +113,8 @@ int skcipher_walk_done(struct skcipher_walk *walk, int res)
*/
res = -EINVAL;
total = 0;
- } else {
- u8 *buf = PTR_ALIGN(walk->buffer, walk->alignmask + 1);
-
- memcpy_to_scatterwalk(&walk->out, buf, n);
- }
+ } else
+ memcpy_to_scatterwalk(&walk->out, walk->out.addr, n);
goto dst_done;
}
@@ -162,7 +156,7 @@ static int skcipher_next_slow(struct skcipher_walk *walk, unsigned int bsize)
{
unsigned alignmask = walk->alignmask;
unsigned n;
- u8 *buffer;
+ void *buffer;
if (!walk->buffer)
walk->buffer = walk->page;
@@ -176,10 +170,11 @@ static int skcipher_next_slow(struct skcipher_walk *walk, unsigned int bsize)
return skcipher_walk_done(walk, -ENOMEM);
walk->buffer = buffer;
}
- walk->dst.virt.addr = PTR_ALIGN(buffer, alignmask + 1);
- walk->src.virt.addr = walk->dst.virt.addr;
- memcpy_from_scatterwalk(walk->src.virt.addr, &walk->in, bsize);
+ buffer = PTR_ALIGN(buffer, alignmask + 1);
+ memcpy_from_scatterwalk(buffer, &walk->in, bsize);
+ walk->out.__addr = buffer;
+ walk->in.__addr = walk->out.addr;
walk->nbytes = bsize;
walk->flags |= SKCIPHER_WALK_SLOW;
@@ -189,7 +184,7 @@ static int skcipher_next_slow(struct skcipher_walk *walk, unsigned int bsize)
static int skcipher_next_copy(struct skcipher_walk *walk)
{
- u8 *tmp = walk->page;
+ void *tmp = walk->page;
skcipher_map_src(walk);
memcpy(tmp, walk->src.virt.addr, walk->nbytes);
@@ -199,8 +194,8 @@ static int skcipher_next_copy(struct skcipher_walk *walk)
* processed (which might be less than walk->nbytes) is known.
*/
- walk->src.virt.addr = tmp;
- walk->dst.virt.addr = tmp;
+ walk->in.__addr = tmp;
+ walk->out.__addr = tmp;
return 0;
}
@@ -214,7 +209,7 @@ static int skcipher_next_fast(struct skcipher_walk *walk)
(u8 *)(sg_page(walk->out.sg) + (walk->out.offset >> PAGE_SHIFT));
skcipher_map_dst(walk);
- walk->src.virt.addr = walk->dst.virt.addr;
+ walk->in.__addr = walk->dst.virt.addr;
if (diff) {
walk->flags |= SKCIPHER_WALK_DIFF;
diff --git a/include/crypto/algapi.h b/include/crypto/algapi.h
index f92e22686a68..6e07bbc04089 100644
--- a/include/crypto/algapi.h
+++ b/include/crypto/algapi.h
@@ -107,14 +107,15 @@ struct crypto_queue {
};
struct scatter_walk {
- struct scatterlist *sg;
- unsigned int offset;
+ /* Must be the first member, see struct skcipher_walk. */
union {
void *const addr;
/* Private API field, do not touch. */
union crypto_no_such_thing *__addr;
};
+ struct scatterlist *sg;
+ unsigned int offset;
};
struct crypto_attr_alg {
diff --git a/include/crypto/internal/skcipher.h b/include/crypto/internal/skcipher.h
index d6ae7a86fed2..c705124432c5 100644
--- a/include/crypto/internal/skcipher.h
+++ b/include/crypto/internal/skcipher.h
@@ -56,15 +56,31 @@ struct crypto_lskcipher_spawn {
struct skcipher_walk {
union {
+ /* Virtual address of the source. */
struct {
- void *addr;
- } virt;
- } src, dst;
+ struct {
+ void *const addr;
+ } virt;
+ } src;
+
+ /* Private field for the API, do not use. */
+ struct scatter_walk in;
+ };
- struct scatter_walk in;
unsigned int nbytes;
- struct scatter_walk out;
+ union {
+ /* Virtual address of the destination. */
+ struct {
+ struct {
+ void *const addr;
+ } virt;
+ } dst;
+
+ /* Private field for the API, do not use. */
+ struct scatter_walk out;
+ };
+
unsigned int total;
u8 *page;