diff options
author | David S. Miller <davem@davemloft.net> | 2010-05-19 14:13:07 +1000 |
---|---|---|
committer | Herbert Xu <herbert@gondor.apana.org.au> | 2010-05-19 14:13:07 +1000 |
commit | bf06099db18a1244957076e51847c644cfe46808 (patch) | |
tree | 80a4e17f939e4dfaf5b2c3b7180c1bd700401831 /include/crypto | |
parent | a8f1a05292db8b410be47fa905669672011f0343 (diff) |
crypto: skcipher - Add ablkcipher_walk interfaces
These are akin to the blkcipher_walk helpers.
The main differences in the async variant are:
1) Only physical walking is supported. We can't hold on to
kmap mappings across the async operation to support virtual
ablkcipher_walk operations anyways.
2) Bounce buffers used for async more need to be persistent and
freed at a later point in time when the async op completes.
Therefore we maintain a list of writeback buffers and require
that the ablkcipher_walk user call the 'complete' operation
so we can copy the bounce buffers out to the real buffers and
free up the bounce buffer chunks.
These interfaces will be used by the new Niagara2 crypto driver.
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Diffstat (limited to 'include/crypto')
-rw-r--r-- | include/crypto/algapi.h | 40 |
1 files changed, 40 insertions, 0 deletions
diff --git a/include/crypto/algapi.h b/include/crypto/algapi.h index fc0d575c71e..59c3e5bd2c0 100644 --- a/include/crypto/algapi.h +++ b/include/crypto/algapi.h @@ -103,6 +103,23 @@ struct blkcipher_walk { unsigned int blocksize; }; +struct ablkcipher_walk { + struct { + struct page *page; + unsigned int offset; + } src, dst; + + struct scatter_walk in; + unsigned int nbytes; + struct scatter_walk out; + unsigned int total; + struct list_head buffers; + u8 *iv_buffer; + u8 *iv; + int flags; + unsigned int blocksize; +}; + extern const struct crypto_type crypto_ablkcipher_type; extern const struct crypto_type crypto_aead_type; extern const struct crypto_type crypto_blkcipher_type; @@ -173,6 +190,12 @@ int blkcipher_walk_virt_block(struct blkcipher_desc *desc, struct blkcipher_walk *walk, unsigned int blocksize); +int ablkcipher_walk_done(struct ablkcipher_request *req, + struct ablkcipher_walk *walk, int err); +int ablkcipher_walk_phys(struct ablkcipher_request *req, + struct ablkcipher_walk *walk); +void __ablkcipher_walk_complete(struct ablkcipher_walk *walk); + static inline void *crypto_tfm_ctx_aligned(struct crypto_tfm *tfm) { return PTR_ALIGN(crypto_tfm_ctx(tfm), @@ -283,6 +306,23 @@ static inline void blkcipher_walk_init(struct blkcipher_walk *walk, walk->total = nbytes; } +static inline void ablkcipher_walk_init(struct ablkcipher_walk *walk, + struct scatterlist *dst, + struct scatterlist *src, + unsigned int nbytes) +{ + walk->in.sg = src; + walk->out.sg = dst; + walk->total = nbytes; + INIT_LIST_HEAD(&walk->buffers); +} + +static inline void ablkcipher_walk_complete(struct ablkcipher_walk *walk) +{ + if (unlikely(!list_empty(&walk->buffers))) + __ablkcipher_walk_complete(walk); +} + static inline struct crypto_async_request *crypto_get_backlog( struct crypto_queue *queue) { |