diff options
author | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-10-11 19:40:14 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-10-11 19:40:14 -0700 |
commit | 038a5008b2f395c85e6e71d6ddf3c684e7c405b0 (patch) | |
tree | 4735eab577e97e5a22c3141e3f60071c8065585e /crypto/blkcipher.c | |
parent | dd6d1844af33acb4edd0a40b1770d091a22c94be (diff) | |
parent | 266918303226cceac7eca38ced30f15f277bd89c (diff) | |
download | linux-038a5008b2f395c85e6e71d6ddf3c684e7c405b0.tar.gz linux-038a5008b2f395c85e6e71d6ddf3c684e7c405b0.tar.bz2 linux-038a5008b2f395c85e6e71d6ddf3c684e7c405b0.zip |
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6
* 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6: (867 commits)
[SKY2]: status polling loop (post merge)
[NET]: Fix NAPI completion handling in some drivers.
[TCP]: Limit processing lost_retrans loop to work-to-do cases
[TCP]: Fix lost_retrans loop vs fastpath problems
[TCP]: No need to re-count fackets_out/sacked_out at RTO
[TCP]: Extract tcp_match_queue_to_sack from sacktag code
[TCP]: Kill almost unused variable pcount from sacktag
[TCP]: Fix mark_head_lost to ignore R-bit when trying to mark L
[TCP]: Add bytes_acked (ABC) clearing to FRTO too
[IPv6]: Update setsockopt(IPV6_MULTICAST_IF) to support RFC 3493, try2
[NETFILTER]: x_tables: add missing ip6t_modulename aliases
[NETFILTER]: nf_conntrack_tcp: fix connection reopening
[QETH]: fix qeth_main.c
[NETLINK]: fib_frontend build fixes
[IPv6]: Export userland ND options through netlink (RDNSS support)
[9P]: build fix with !CONFIG_SYSCTL
[NET]: Fix dev_put() and dev_hold() comments
[NET]: make netlink user -> kernel interface synchronious
[NET]: unify netlink kernel socket recognition
[NET]: cleanup 3rd argument in netlink_sendskb
...
Fix up conflicts manually in Documentation/feature-removal-schedule.txt
and my new least favourite crap, the "mod_devicetable" support in the
files include/linux/mod_devicetable.h and scripts/mod/file2alias.c.
(The latter files seem to be explicitly _designed_ to get conflicts when
different subsystems work with them - that have an absolutely horrid
lack of subsystem separation!)
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'crypto/blkcipher.c')
-rw-r--r-- | crypto/blkcipher.c | 57 |
1 files changed, 37 insertions, 20 deletions
diff --git a/crypto/blkcipher.c b/crypto/blkcipher.c index d8f8ec320213..f6c67f9d4e5c 100644 --- a/crypto/blkcipher.c +++ b/crypto/blkcipher.c @@ -65,7 +65,7 @@ static inline void blkcipher_unmap_dst(struct blkcipher_walk *walk) static inline u8 *blkcipher_get_spot(u8 *start, unsigned int len) { u8 *end_page = (u8 *)(((unsigned long)(start + len - 1)) & PAGE_MASK); - return start > end_page ? start : end_page; + return max(start, end_page); } static inline unsigned int blkcipher_done_slow(struct crypto_blkcipher *tfm, @@ -84,8 +84,6 @@ static inline unsigned int blkcipher_done_slow(struct crypto_blkcipher *tfm, static inline unsigned int blkcipher_done_fast(struct blkcipher_walk *walk, unsigned int n) { - n = walk->nbytes - n; - if (walk->flags & BLKCIPHER_WALK_COPY) { blkcipher_map_dst(walk); memcpy(walk->dst.virt.addr, walk->page, n); @@ -109,13 +107,15 @@ int blkcipher_walk_done(struct blkcipher_desc *desc, unsigned int nbytes = 0; if (likely(err >= 0)) { - unsigned int bsize = crypto_blkcipher_blocksize(tfm); - unsigned int n; + unsigned int n = walk->nbytes - err; if (likely(!(walk->flags & BLKCIPHER_WALK_SLOW))) - n = blkcipher_done_fast(walk, err); - else - n = blkcipher_done_slow(tfm, walk, bsize); + n = blkcipher_done_fast(walk, n); + else if (WARN_ON(err)) { + err = -EINVAL; + goto err; + } else + n = blkcipher_done_slow(tfm, walk, n); nbytes = walk->total - n; err = 0; @@ -132,6 +132,7 @@ int blkcipher_walk_done(struct blkcipher_desc *desc, return blkcipher_walk_next(desc, walk); } +err: if (walk->iv != desc->info) memcpy(desc->info, walk->iv, crypto_blkcipher_ivsize(tfm)); if (walk->buffer != walk->page) @@ -149,6 +150,7 @@ static inline int blkcipher_next_slow(struct blkcipher_desc *desc, unsigned int alignmask) { unsigned int n; + unsigned aligned_bsize = ALIGN(bsize, alignmask + 1); if (walk->buffer) goto ok; @@ -157,7 +159,7 @@ static inline int blkcipher_next_slow(struct blkcipher_desc *desc, if (walk->buffer) goto ok; - n = bsize * 3 - (alignmask + 1) + + n = aligned_bsize * 3 - (alignmask + 1) + (alignmask & ~(crypto_tfm_ctx_alignment() - 1)); walk->buffer = kmalloc(n, GFP_ATOMIC); if (!walk->buffer) @@ -167,8 +169,8 @@ ok: walk->dst.virt.addr = (u8 *)ALIGN((unsigned long)walk->buffer, alignmask + 1); walk->dst.virt.addr = blkcipher_get_spot(walk->dst.virt.addr, bsize); - walk->src.virt.addr = blkcipher_get_spot(walk->dst.virt.addr + bsize, - bsize); + walk->src.virt.addr = blkcipher_get_spot(walk->dst.virt.addr + + aligned_bsize, bsize); scatterwalk_copychunks(walk->src.virt.addr, &walk->in, bsize, 0); @@ -224,12 +226,12 @@ static int blkcipher_walk_next(struct blkcipher_desc *desc, { struct crypto_blkcipher *tfm = desc->tfm; unsigned int alignmask = crypto_blkcipher_alignmask(tfm); - unsigned int bsize = crypto_blkcipher_blocksize(tfm); + unsigned int bsize; unsigned int n; int err; n = walk->total; - if (unlikely(n < bsize)) { + if (unlikely(n < crypto_blkcipher_blocksize(tfm))) { desc->flags |= CRYPTO_TFM_RES_BAD_BLOCK_LEN; return blkcipher_walk_done(desc, walk, -EINVAL); } @@ -246,6 +248,7 @@ static int blkcipher_walk_next(struct blkcipher_desc *desc, } } + bsize = min(walk->blocksize, n); n = scatterwalk_clamp(&walk->in, n); n = scatterwalk_clamp(&walk->out, n); @@ -276,9 +279,11 @@ static inline int blkcipher_copy_iv(struct blkcipher_walk *walk, struct crypto_blkcipher *tfm, unsigned int alignmask) { - unsigned bs = crypto_blkcipher_blocksize(tfm); + unsigned bs = walk->blocksize; unsigned int ivsize = crypto_blkcipher_ivsize(tfm); - unsigned int size = bs * 2 + ivsize + max(bs, ivsize) - (alignmask + 1); + unsigned aligned_bs = ALIGN(bs, alignmask + 1); + unsigned int size = aligned_bs * 2 + ivsize + max(aligned_bs, ivsize) - + (alignmask + 1); u8 *iv; size += alignmask & ~(crypto_tfm_ctx_alignment() - 1); @@ -287,8 +292,8 @@ static inline int blkcipher_copy_iv(struct blkcipher_walk *walk, return -ENOMEM; iv = (u8 *)ALIGN((unsigned long)walk->buffer, alignmask + 1); - iv = blkcipher_get_spot(iv, bs) + bs; - iv = blkcipher_get_spot(iv, bs) + bs; + iv = blkcipher_get_spot(iv, bs) + aligned_bs; + iv = blkcipher_get_spot(iv, bs) + aligned_bs; iv = blkcipher_get_spot(iv, ivsize); walk->iv = memcpy(iv, walk->iv, ivsize); @@ -299,6 +304,7 @@ int blkcipher_walk_virt(struct blkcipher_desc *desc, struct blkcipher_walk *walk) { walk->flags &= ~BLKCIPHER_WALK_PHYS; + walk->blocksize = crypto_blkcipher_blocksize(desc->tfm); return blkcipher_walk_first(desc, walk); } EXPORT_SYMBOL_GPL(blkcipher_walk_virt); @@ -307,6 +313,7 @@ int blkcipher_walk_phys(struct blkcipher_desc *desc, struct blkcipher_walk *walk) { walk->flags |= BLKCIPHER_WALK_PHYS; + walk->blocksize = crypto_blkcipher_blocksize(desc->tfm); return blkcipher_walk_first(desc, walk); } EXPORT_SYMBOL_GPL(blkcipher_walk_phys); @@ -339,7 +346,18 @@ static int blkcipher_walk_first(struct blkcipher_desc *desc, return blkcipher_walk_next(desc, walk); } -static int setkey_unaligned(struct crypto_tfm *tfm, const u8 *key, unsigned int keylen) +int blkcipher_walk_virt_block(struct blkcipher_desc *desc, + struct blkcipher_walk *walk, + unsigned int blocksize) +{ + walk->flags &= ~BLKCIPHER_WALK_PHYS; + walk->blocksize = blocksize; + return blkcipher_walk_first(desc, walk); +} +EXPORT_SYMBOL_GPL(blkcipher_walk_virt_block); + +static int setkey_unaligned(struct crypto_tfm *tfm, const u8 *key, + unsigned int keylen) { struct blkcipher_alg *cipher = &tfm->__crt_alg->cra_blkcipher; unsigned long alignmask = crypto_tfm_alg_alignmask(tfm); @@ -360,8 +378,7 @@ static int setkey_unaligned(struct crypto_tfm *tfm, const u8 *key, unsigned int return ret; } -static int setkey(struct crypto_tfm *tfm, const u8 *key, - unsigned int keylen) +static int setkey(struct crypto_tfm *tfm, const u8 *key, unsigned int keylen) { struct blkcipher_alg *cipher = &tfm->__crt_alg->cra_blkcipher; unsigned long alignmask = crypto_tfm_alg_alignmask(tfm); |