void twofish_enc_blk_ctr_3way(void *ctx, u128 *dst, const u128 *src, u128 *iv) { be128 ctrblks[3]; if (dst != src) { dst[0] = src[0]; dst[1] = src[1]; dst[2] = src[2]; } u128_to_be128(&ctrblks[0], iv); u128_inc(iv); u128_to_be128(&ctrblks[1], iv); u128_inc(iv); u128_to_be128(&ctrblks[2], iv); u128_inc(iv); twofish_enc_blk_xor_3way(ctx, (u8 *)dst, (u8 *)ctrblks); }
void twofish_enc_blk_ctr(void *ctx, u128 *dst, const u128 *src, u128 *iv) { be128 ctrblk; if (dst != src) *dst = *src; u128_to_be128(&ctrblk, iv); u128_inc(iv); twofish_enc_blk(ctx, (u8 *)&ctrblk, (u8 *)&ctrblk); u128_xor(dst, dst, (u128 *)&ctrblk); }
static void twofish_enc_blk_ctr_xway(void *ctx, u128 *dst, const u128 *src, u128 *iv) { be128 ctrblks[TWOFISH_PARALLEL_BLOCKS]; unsigned int i; for (i = 0; i < TWOFISH_PARALLEL_BLOCKS; i++) { if (dst != src) dst[i] = src[i]; u128_to_be128(&ctrblks[i], iv); u128_inc(iv); } twofish_enc_blk_xway_xor(ctx, (u8 *)dst, (u8 *)ctrblks); }
static unsigned int __ctr_crypt(struct blkcipher_desc *desc, struct blkcipher_walk *walk) { struct twofish_ctx *ctx = crypto_blkcipher_ctx(desc->tfm); unsigned int bsize = TF_BLOCK_SIZE; unsigned int nbytes = walk->nbytes; u128 *src = (u128 *)walk->src.virt.addr; u128 *dst = (u128 *)walk->dst.virt.addr; u128 ctrblk; be128 ctrblocks[3]; be128_to_u128(&ctrblk, (be128 *)walk->iv); /* Process three block batch */ if (nbytes >= bsize * 3) { do { if (dst != src) { dst[0] = src[0]; dst[1] = src[1]; dst[2] = src[2]; } /* create ctrblks for parallel encrypt */ u128_to_be128(&ctrblocks[0], &ctrblk); u128_inc(&ctrblk); u128_to_be128(&ctrblocks[1], &ctrblk); u128_inc(&ctrblk); u128_to_be128(&ctrblocks[2], &ctrblk); u128_inc(&ctrblk); twofish_enc_blk_xor_3way(ctx, (u8 *)dst, (u8 *)ctrblocks); src += 3; dst += 3; nbytes -= bsize * 3; } while (nbytes >= bsize * 3); if (nbytes < bsize) goto done; } /* Handle leftovers */ do { if (dst != src) *dst = *src; u128_to_be128(&ctrblocks[0], &ctrblk); u128_inc(&ctrblk); twofish_enc_blk(ctx, (u8 *)ctrblocks, (u8 *)ctrblocks); u128_xor(dst, dst, (u128 *)ctrblocks); src += 1; dst += 1; nbytes -= bsize; } while (nbytes >= bsize); done: u128_to_be128((be128 *)walk->iv, &ctrblk); return nbytes; }