static inline int blkcipher_next_slow(struct blkcipher_desc *desc, struct blkcipher_walk *walk, unsigned int bsize, unsigned int alignmask) { unsigned int n; unsigned aligned_bsize = ALIGN(bsize, alignmask + 1); if (walk->buffer) goto ok; walk->buffer = walk->page; if (walk->buffer) goto ok; n = aligned_bsize * 3 - (alignmask + 1) + (alignmask & ~(crypto_tfm_ctx_alignment() - 1)); walk->buffer = kmalloc(n, GFP_ATOMIC); if (!walk->buffer) return blkcipher_walk_done(desc, walk, -ENOMEM); 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 + aligned_bsize, bsize); scatterwalk_copychunks(walk->src.virt.addr, &walk->in, bsize, 0); walk->nbytes = bsize; walk->flags |= BLKCIPHER_WALK_SLOW; return 0; }
static inline unsigned int blkcipher_done_slow(struct blkcipher_walk *walk, unsigned int bsize) { u8 *addr; addr = (u8 *)ALIGN((unsigned long)walk->buffer, walk->alignmask + 1); addr = blkcipher_get_spot(addr, bsize); scatterwalk_copychunks(addr, &walk->out, bsize, 1); return bsize; }
static inline int blkcipher_copy_iv(struct blkcipher_walk *walk) { unsigned bs = walk->walk_blocksize; unsigned aligned_bs = ALIGN(bs, walk->alignmask + 1); unsigned int size = aligned_bs * 2 + walk->ivsize + max(aligned_bs, walk->ivsize) - (walk->alignmask + 1); u8 *iv; size += walk->alignmask & ~(crypto_tfm_ctx_alignment() - 1); walk->buffer = kmalloc(size, GFP_ATOMIC); if (!walk->buffer) return -ENOMEM; iv = (u8 *)ALIGN((unsigned long)walk->buffer, walk->alignmask + 1); iv = blkcipher_get_spot(iv, bs) + aligned_bs; iv = blkcipher_get_spot(iv, bs) + aligned_bs; iv = blkcipher_get_spot(iv, walk->ivsize); walk->iv = memcpy(iv, walk->iv, walk->ivsize); return 0; }
static inline int blkcipher_copy_iv(struct blkcipher_walk *walk, struct crypto_blkcipher *tfm, unsigned int alignmask) { unsigned bs = crypto_blkcipher_blocksize(tfm); unsigned int ivsize = crypto_blkcipher_ivsize(tfm); unsigned int size = bs * 2 + ivsize + max(bs, ivsize) - (alignmask + 1); u8 *iv; size += alignmask & ~(crypto_tfm_ctx_alignment() - 1); walk->buffer = kmalloc(size, GFP_ATOMIC); if (!walk->buffer) 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, ivsize); walk->iv = memcpy(iv, walk->iv, ivsize); return 0; }