I think I might understand how it works now after looking at some kernel code and comparing it to what is on wiki. However, it would be great if someone could double check it.
The kernel code for CBC mode:
Code:
static int crypto_cbc_encrypt_segment(struct blkcipher_desc *desc,
struct blkcipher_walk *walk,
struct crypto_cipher *tfm)
{
void (*fn)(struct crypto_tfm *, u8 *, const u8 *) =
crypto_cipher_alg(tfm)->cia_encrypt;
int bsize = crypto_cipher_blocksize(tfm);
unsigned int nbytes = walk->nbytes;
u8 *src = walk->src.virt.addr;
u8 *dst = walk->dst.virt.addr;
u8 *iv = walk->iv;
do {
crypto_xor(iv, src, bsize);
fn(crypto_cipher_tfm(tfm), dst, iv);
memcpy(iv, dst, bsize);
src += bsize;
dst += bsize;
} while ((nbytes -= bsize) >= bsize);
return nbytes;
}
And for CTR mode:
Code:
static int crypto_ctr_crypt_segment(struct blkcipher_walk *walk,
struct crypto_cipher *tfm)
{
void (*fn)(struct crypto_tfm *, u8 *, const u8 *) =
crypto_cipher_alg(tfm)->cia_encrypt;
unsigned int bsize = crypto_cipher_blocksize(tfm);
u8 *ctrblk = walk->iv;
u8 *src = walk->src.virt.addr;
u8 *dst = walk->dst.virt.addr;
unsigned int nbytes = walk->nbytes;
do {
/* create keystream */
fn(crypto_cipher_tfm(tfm), dst, ctrblk);
crypto_xor(dst, src, bsize);
/* increment counter in counterblock */
crypto_inc(ctrblk, bsize);
src += bsize;
dst += bsize;
} while ((nbytes -= bsize) >= bsize);
return nbytes;
}
The essiv is generated in different ways depending on the options you specify, the code seems to be in 'crypto/eseqiv.c'. All that is changed by it is the IV.
Using the schemas on wiki:
https://en.wikipedia.org/wiki/Block_...n#Common_modes
It seems that in CTR mode, the IV is the counter block plus nonce.
Quote:
Note that the nonce in this diagram is the same thing as the initialization vector (IV) in the other diagrams. The IV/nonce and the counter can be combined together using any lossless operation (concatenation, addition, or XOR) to produce the actual unique counter block for encryption.
|
So, then is ESSIV better than plain for CTR mode ? It might be, because the IV/nonce needs to be pseudorandom and unknown. Plain mode is not used for CBC because:
Quote:
The usual methods for generating IVs are predictable sequences of numbers based on, for example, time stamp or sector number, and permits certain attacks such as a watermarking attack. ESSIV prevents such attacks by generating IVs from a combination of the sector number SN with the hash of the key. It is the combination with the key in form of a hash that makes the IV unpredictable.
|
https://en.wikipedia.org/wiki/Disk_e...or_.28ESSIV.29
So, one can conclude that ESSIV is better than plain for CTR as well, because the IV must be unpredictable.