Skip to content

Commit 75ecb23

Browse files
committedMay 21, 2014
crypto: hash - Add real ahash walk interface
Although the existing hash walk interface has already been used by a number of ahash crypto drivers, it turns out that none of them were really asynchronous. They were all essentially polling for completion. That's why nobody has noticed until now that the walk interface couldn't work with a real asynchronous driver since the memory is mapped using kmap_atomic. As we now have a use-case for a real ahash implementation on x86, this patch creates a minimal ahash walk interface. Basically it just calls kmap instead of kmap_atomic and does away with the crypto_yield call. Real ahash crypto drivers don't need to yield since by definition they won't be hogging the CPU. Signed-off-by: Herbert Xu <[email protected]>
1 parent 0118a55 commit 75ecb23

File tree

2 files changed

+49
-5
lines changed

2 files changed

+49
-5
lines changed
 

‎crypto/ahash.c

+36-5
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515

1616
#include <crypto/internal/hash.h>
1717
#include <crypto/scatterwalk.h>
18+
#include <linux/bug.h>
1819
#include <linux/err.h>
1920
#include <linux/kernel.h>
2021
#include <linux/module.h>
@@ -46,7 +47,10 @@ static int hash_walk_next(struct crypto_hash_walk *walk)
4647
unsigned int nbytes = min(walk->entrylen,
4748
((unsigned int)(PAGE_SIZE)) - offset);
4849

49-
walk->data = kmap_atomic(walk->pg);
50+
if (walk->flags & CRYPTO_ALG_ASYNC)
51+
walk->data = kmap(walk->pg);
52+
else
53+
walk->data = kmap_atomic(walk->pg);
5054
walk->data += offset;
5155

5256
if (offset & alignmask) {
@@ -93,8 +97,16 @@ int crypto_hash_walk_done(struct crypto_hash_walk *walk, int err)
9397
return nbytes;
9498
}
9599

96-
kunmap_atomic(walk->data);
97-
crypto_yield(walk->flags);
100+
if (walk->flags & CRYPTO_ALG_ASYNC)
101+
kunmap(walk->pg);
102+
else {
103+
kunmap_atomic(walk->data);
104+
/*
105+
* The may sleep test only makes sense for sync users.
106+
* Async users don't need to sleep here anyway.
107+
*/
108+
crypto_yield(walk->flags);
109+
}
98110

99111
if (err)
100112
return err;
@@ -124,12 +136,31 @@ int crypto_hash_walk_first(struct ahash_request *req,
124136

125137
walk->alignmask = crypto_ahash_alignmask(crypto_ahash_reqtfm(req));
126138
walk->sg = req->src;
127-
walk->flags = req->base.flags;
139+
walk->flags = req->base.flags & CRYPTO_TFM_REQ_MASK;
128140

129141
return hash_walk_new_entry(walk);
130142
}
131143
EXPORT_SYMBOL_GPL(crypto_hash_walk_first);
132144

145+
int crypto_ahash_walk_first(struct ahash_request *req,
146+
struct crypto_hash_walk *walk)
147+
{
148+
walk->total = req->nbytes;
149+
150+
if (!walk->total)
151+
return 0;
152+
153+
walk->alignmask = crypto_ahash_alignmask(crypto_ahash_reqtfm(req));
154+
walk->sg = req->src;
155+
walk->flags = req->base.flags & CRYPTO_TFM_REQ_MASK;
156+
walk->flags |= CRYPTO_ALG_ASYNC;
157+
158+
BUILD_BUG_ON(CRYPTO_TFM_REQ_MASK & CRYPTO_ALG_ASYNC);
159+
160+
return hash_walk_new_entry(walk);
161+
}
162+
EXPORT_SYMBOL_GPL(crypto_ahash_walk_first);
163+
133164
int crypto_hash_walk_first_compat(struct hash_desc *hdesc,
134165
struct crypto_hash_walk *walk,
135166
struct scatterlist *sg, unsigned int len)
@@ -141,7 +172,7 @@ int crypto_hash_walk_first_compat(struct hash_desc *hdesc,
141172

142173
walk->alignmask = crypto_hash_alignmask(hdesc->tfm);
143174
walk->sg = sg;
144-
walk->flags = hdesc->flags;
175+
walk->flags = hdesc->flags & CRYPTO_TFM_REQ_MASK;
145176

146177
return hash_walk_new_entry(walk);
147178
}

‎include/crypto/internal/hash.h

+13
Original file line numberDiff line numberDiff line change
@@ -55,15 +55,28 @@ extern const struct crypto_type crypto_ahash_type;
5555
int crypto_hash_walk_done(struct crypto_hash_walk *walk, int err);
5656
int crypto_hash_walk_first(struct ahash_request *req,
5757
struct crypto_hash_walk *walk);
58+
int crypto_ahash_walk_first(struct ahash_request *req,
59+
struct crypto_hash_walk *walk);
5860
int crypto_hash_walk_first_compat(struct hash_desc *hdesc,
5961
struct crypto_hash_walk *walk,
6062
struct scatterlist *sg, unsigned int len);
6163

64+
static inline int crypto_ahash_walk_done(struct crypto_hash_walk *walk,
65+
int err)
66+
{
67+
return crypto_hash_walk_done(walk, err);
68+
}
69+
6270
static inline int crypto_hash_walk_last(struct crypto_hash_walk *walk)
6371
{
6472
return !(walk->entrylen | walk->total);
6573
}
6674

75+
static inline int crypto_ahash_walk_last(struct crypto_hash_walk *walk)
76+
{
77+
return crypto_hash_walk_last(walk);
78+
}
79+
6780
int crypto_register_ahash(struct ahash_alg *alg);
6881
int crypto_unregister_ahash(struct ahash_alg *alg);
6982
int ahash_register_instance(struct crypto_template *tmpl,

0 commit comments

Comments
 (0)
Please sign in to comment.