Add a flag that tells that the algorithm reads the data only once when encrypting. It will be used by dm-crypt to skip a copy operation if not needed. Signed-off-by: Mikulas Patocka --- crypto/aes_generic.c | 2 +- crypto/anubis.c | 2 +- crypto/arc4.c | 2 +- crypto/blkcipher.c | 2 +- crypto/blowfish.c | 2 +- crypto/camellia.c | 2 +- crypto/cast5.c | 2 +- crypto/cast6.c | 2 +- crypto/cbc.c | 2 +- crypto/cryptd.c | 2 +- crypto/crypto_null.c | 2 +- crypto/ctr.c | 2 +- crypto/des_generic.c | 4 ++-- crypto/ecb.c | 2 +- crypto/fcrypt.c | 2 +- crypto/khazad.c | 2 +- crypto/lrw.c | 2 +- crypto/pcbc.c | 2 +- crypto/salsa20_generic.c | 2 +- crypto/seed.c | 2 +- crypto/serpent.c | 4 ++-- crypto/tea.c | 4 ++-- crypto/twofish.c | 2 +- crypto/xts.c | 2 +- include/linux/crypto.h | 9 +++++++++ 25 files changed, 36 insertions(+), 27 deletions(-) Index: linux-2.6.26-rc4/include/linux/crypto.h =================================================================== --- linux-2.6.26-rc4.orig/include/linux/crypto.h 2008-06-02 23:13:35.000000000 +0200 +++ linux-2.6.26-rc4/include/linux/crypto.h 2008-06-03 16:26:28.000000000 +0200 @@ -59,6 +59,15 @@ #define CRYPTO_ALG_GENIV 0x00000200 /* + * The encryption algorithm reads the data only once. So it can encrypt + * data while they change. + * + * This is useful for disk encryption, so that the sector doesn't have + * to be copied to temporary space before encrypting. + */ +#define CRYPTO_ALG_ENCRYPT_READ_ONCE 0x00000400 + +/* * Transform masks and values (for crt_flags). */ #define CRYPTO_TFM_REQ_MASK 0x000fff00 Index: linux-2.6.26-rc4/crypto/cbc.c =================================================================== --- linux-2.6.26-rc4.orig/crypto/cbc.c 2008-06-02 22:08:59.000000000 +0200 +++ linux-2.6.26-rc4/crypto/cbc.c 2008-06-03 16:26:28.000000000 +0200 @@ -234,7 +234,7 @@ static struct crypto_instance *crypto_cb if (IS_ERR(inst)) goto out_put_alg; - inst->alg.cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER; + inst->alg.cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER | (alg->cra_flags & CRYPTO_ALG_ENCRYPT_READ_ONCE); inst->alg.cra_priority = alg->cra_priority; inst->alg.cra_blocksize = alg->cra_blocksize; inst->alg.cra_alignmask = alg->cra_alignmask; Index: linux-2.6.26-rc4/crypto/ecb.c =================================================================== --- linux-2.6.26-rc4.orig/crypto/ecb.c 2008-06-02 22:08:59.000000000 +0200 +++ linux-2.6.26-rc4/crypto/ecb.c 2008-06-03 16:26:28.000000000 +0200 @@ -134,7 +134,7 @@ static struct crypto_instance *crypto_ec if (IS_ERR(inst)) goto out_put_alg; - inst->alg.cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER; + inst->alg.cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER | (alg->cra_flags & CRYPTO_ALG_ENCRYPT_READ_ONCE); inst->alg.cra_priority = alg->cra_priority; inst->alg.cra_blocksize = alg->cra_blocksize; inst->alg.cra_alignmask = alg->cra_alignmask; Index: linux-2.6.26-rc4/crypto/ctr.c =================================================================== --- linux-2.6.26-rc4.orig/crypto/ctr.c 2008-06-02 22:08:59.000000000 +0200 +++ linux-2.6.26-rc4/crypto/ctr.c 2008-06-03 16:26:28.000000000 +0200 @@ -200,7 +200,7 @@ static struct crypto_instance *crypto_ct if (IS_ERR(inst)) goto out; - inst->alg.cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER; + inst->alg.cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER | CRYPTO_ALG_ENCRYPT_READ_ONCE; inst->alg.cra_priority = alg->cra_priority; inst->alg.cra_blocksize = 1; inst->alg.cra_alignmask = alg->cra_alignmask | (__alignof__(u32) - 1); Index: linux-2.6.26-rc4/crypto/lrw.c =================================================================== --- linux-2.6.26-rc4.orig/crypto/lrw.c 2008-06-02 23:10:44.000000000 +0200 +++ linux-2.6.26-rc4/crypto/lrw.c 2008-06-03 16:26:28.000000000 +0200 @@ -248,7 +248,7 @@ static struct crypto_instance *alloc(str if (IS_ERR(inst)) goto out_put_alg; - inst->alg.cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER; + inst->alg.cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER | CRYPTO_ALG_ENCRYPT_READ_ONCE; inst->alg.cra_priority = alg->cra_priority; inst->alg.cra_blocksize = alg->cra_blocksize; Index: linux-2.6.26-rc4/crypto/xts.c =================================================================== --- linux-2.6.26-rc4.orig/crypto/xts.c 2008-06-02 22:08:59.000000000 +0200 +++ linux-2.6.26-rc4/crypto/xts.c 2008-06-03 16:26:28.000000000 +0200 @@ -230,7 +230,7 @@ static struct crypto_instance *alloc(str if (IS_ERR(inst)) goto out_put_alg; - inst->alg.cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER; + inst->alg.cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER | CRYPTO_ALG_ENCRYPT_READ_ONCE; inst->alg.cra_priority = alg->cra_priority; inst->alg.cra_blocksize = alg->cra_blocksize; Index: linux-2.6.26-rc4/crypto/aes_generic.c =================================================================== --- linux-2.6.26-rc4.orig/crypto/aes_generic.c 2008-06-02 23:10:44.000000000 +0200 +++ linux-2.6.26-rc4/crypto/aes_generic.c 2008-06-03 16:26:28.000000000 +0200 @@ -472,7 +472,7 @@ static struct crypto_alg aes_alg = { .cra_name = "aes", .cra_driver_name = "aes-generic", .cra_priority = 100, - .cra_flags = CRYPTO_ALG_TYPE_CIPHER, + .cra_flags = CRYPTO_ALG_TYPE_CIPHER | CRYPTO_ALG_ENCRYPT_READ_ONCE, .cra_blocksize = AES_BLOCK_SIZE, .cra_ctxsize = sizeof(struct crypto_aes_ctx), .cra_alignmask = 3, Index: linux-2.6.26-rc4/crypto/cryptd.c =================================================================== --- linux-2.6.26-rc4.orig/crypto/cryptd.c 2008-06-02 23:10:44.000000000 +0200 +++ linux-2.6.26-rc4/crypto/cryptd.c 2008-06-03 16:26:28.000000000 +0200 @@ -238,7 +238,7 @@ static struct crypto_instance *cryptd_al if (IS_ERR(inst)) goto out_put_alg; - inst->alg.cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC; + inst->alg.cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC | (alg->cra_flags & CRYPTO_ALG_ENCRYPT_READ_ONCE); inst->alg.cra_type = &crypto_ablkcipher_type; inst->alg.cra_ablkcipher.ivsize = alg->cra_blkcipher.ivsize; Index: linux-2.6.26-rc4/crypto/pcbc.c =================================================================== --- linux-2.6.26-rc4.orig/crypto/pcbc.c 2008-06-02 22:08:59.000000000 +0200 +++ linux-2.6.26-rc4/crypto/pcbc.c 2008-06-03 16:26:28.000000000 +0200 @@ -240,7 +240,7 @@ static struct crypto_instance *crypto_pc if (IS_ERR(inst)) goto out_put_alg; - inst->alg.cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER; + inst->alg.cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER | (alg->cra_flags & CRYPTO_ALG_ENCRYPT_READ_ONCE); inst->alg.cra_priority = alg->cra_priority; inst->alg.cra_blocksize = alg->cra_blocksize; inst->alg.cra_alignmask = alg->cra_alignmask; Index: linux-2.6.26-rc4/crypto/salsa20_generic.c =================================================================== --- linux-2.6.26-rc4.orig/crypto/salsa20_generic.c 2008-06-02 23:10:44.000000000 +0200 +++ linux-2.6.26-rc4/crypto/salsa20_generic.c 2008-06-03 16:26:28.000000000 +0200 @@ -218,7 +218,7 @@ static struct crypto_alg alg = { .cra_name = "salsa20", .cra_driver_name = "salsa20-generic", .cra_priority = 100, - .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER, + .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER | CRYPTO_ALG_ENCRYPT_READ_ONCE, .cra_type = &crypto_blkcipher_type, .cra_blocksize = 1, .cra_ctxsize = sizeof(struct salsa20_ctx), Index: linux-2.6.26-rc4/crypto/anubis.c =================================================================== --- linux-2.6.26-rc4.orig/crypto/anubis.c 2008-06-02 23:10:44.000000000 +0200 +++ linux-2.6.26-rc4/crypto/anubis.c 2008-06-03 16:26:28.000000000 +0200 @@ -673,7 +673,7 @@ static void anubis_decrypt(struct crypto static struct crypto_alg anubis_alg = { .cra_name = "anubis", - .cra_flags = CRYPTO_ALG_TYPE_CIPHER, + .cra_flags = CRYPTO_ALG_TYPE_CIPHER | CRYPTO_ALG_ENCRYPT_READ_ONCE, .cra_blocksize = ANUBIS_BLOCK_SIZE, .cra_ctxsize = sizeof (struct anubis_ctx), .cra_alignmask = 3, Index: linux-2.6.26-rc4/crypto/arc4.c =================================================================== --- linux-2.6.26-rc4.orig/crypto/arc4.c 2008-06-02 22:08:59.000000000 +0200 +++ linux-2.6.26-rc4/crypto/arc4.c 2008-06-03 16:26:28.000000000 +0200 @@ -72,7 +72,7 @@ static void arc4_crypt(struct crypto_tfm static struct crypto_alg arc4_alg = { .cra_name = "arc4", - .cra_flags = CRYPTO_ALG_TYPE_CIPHER, + .cra_flags = CRYPTO_ALG_TYPE_CIPHER | CRYPTO_ALG_ENCRYPT_READ_ONCE, .cra_blocksize = ARC4_BLOCK_SIZE, .cra_ctxsize = sizeof(struct arc4_ctx), .cra_module = THIS_MODULE, Index: linux-2.6.26-rc4/crypto/blowfish.c =================================================================== --- linux-2.6.26-rc4.orig/crypto/blowfish.c 2008-06-02 23:10:44.000000000 +0200 +++ linux-2.6.26-rc4/crypto/blowfish.c 2008-06-03 16:26:28.000000000 +0200 @@ -451,7 +451,7 @@ static int bf_setkey(struct crypto_tfm * static struct crypto_alg alg = { .cra_name = "blowfish", - .cra_flags = CRYPTO_ALG_TYPE_CIPHER, + .cra_flags = CRYPTO_ALG_TYPE_CIPHER | CRYPTO_ALG_ENCRYPT_READ_ONCE, .cra_blocksize = BF_BLOCK_SIZE, .cra_ctxsize = sizeof(struct bf_ctx), .cra_alignmask = 3, Index: linux-2.6.26-rc4/crypto/camellia.c =================================================================== --- linux-2.6.26-rc4.orig/crypto/camellia.c 2008-06-02 22:08:59.000000000 +0200 +++ linux-2.6.26-rc4/crypto/camellia.c 2008-06-03 16:26:28.000000000 +0200 @@ -1094,7 +1094,7 @@ static struct crypto_alg camellia_alg = .cra_name = "camellia", .cra_driver_name = "camellia-generic", .cra_priority = 100, - .cra_flags = CRYPTO_ALG_TYPE_CIPHER, + .cra_flags = CRYPTO_ALG_TYPE_CIPHER | CRYPTO_ALG_ENCRYPT_READ_ONCE, .cra_blocksize = CAMELLIA_BLOCK_SIZE, .cra_ctxsize = sizeof(struct camellia_ctx), .cra_alignmask = 3, Index: linux-2.6.26-rc4/crypto/cast5.c =================================================================== --- linux-2.6.26-rc4.orig/crypto/cast5.c 2008-06-02 23:10:44.000000000 +0200 +++ linux-2.6.26-rc4/crypto/cast5.c 2008-06-03 16:26:28.000000000 +0200 @@ -800,7 +800,7 @@ static int cast5_setkey(struct crypto_tf static struct crypto_alg alg = { .cra_name = "cast5", - .cra_flags = CRYPTO_ALG_TYPE_CIPHER, + .cra_flags = CRYPTO_ALG_TYPE_CIPHER | CRYPTO_ALG_ENCRYPT_READ_ONCE, .cra_blocksize = CAST5_BLOCK_SIZE, .cra_ctxsize = sizeof(struct cast5_ctx), .cra_alignmask = 3, Index: linux-2.6.26-rc4/crypto/cast6.c =================================================================== --- linux-2.6.26-rc4.orig/crypto/cast6.c 2008-06-02 23:10:44.000000000 +0200 +++ linux-2.6.26-rc4/crypto/cast6.c 2008-06-03 16:26:28.000000000 +0200 @@ -512,7 +512,7 @@ static void cast6_decrypt(struct crypto_ static struct crypto_alg alg = { .cra_name = "cast6", - .cra_flags = CRYPTO_ALG_TYPE_CIPHER, + .cra_flags = CRYPTO_ALG_TYPE_CIPHER | CRYPTO_ALG_ENCRYPT_READ_ONCE, .cra_blocksize = CAST6_BLOCK_SIZE, .cra_ctxsize = sizeof(struct cast6_ctx), .cra_alignmask = 3, Index: linux-2.6.26-rc4/crypto/crypto_null.c =================================================================== --- linux-2.6.26-rc4.orig/crypto/crypto_null.c 2008-06-02 23:10:44.000000000 +0200 +++ linux-2.6.26-rc4/crypto/crypto_null.c 2008-06-03 16:26:28.000000000 +0200 @@ -123,7 +123,7 @@ static struct crypto_alg skcipher_null = .cra_name = "ecb(cipher_null)", .cra_driver_name = "ecb-cipher_null", .cra_priority = 100, - .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER, + .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER | CRYPTO_ALG_ENCRYPT_READ_ONCE, .cra_blocksize = NULL_BLOCK_SIZE, .cra_type = &crypto_blkcipher_type, .cra_ctxsize = 0, Index: linux-2.6.26-rc4/crypto/des_generic.c =================================================================== --- linux-2.6.26-rc4.orig/crypto/des_generic.c 2008-06-02 23:10:44.000000000 +0200 +++ linux-2.6.26-rc4/crypto/des_generic.c 2008-06-03 16:26:28.000000000 +0200 @@ -945,7 +945,7 @@ static void des3_ede_decrypt(struct cryp static struct crypto_alg des_alg = { .cra_name = "des", - .cra_flags = CRYPTO_ALG_TYPE_CIPHER, + .cra_flags = CRYPTO_ALG_TYPE_CIPHER | CRYPTO_ALG_ENCRYPT_READ_ONCE, .cra_blocksize = DES_BLOCK_SIZE, .cra_ctxsize = sizeof(struct des_ctx), .cra_module = THIS_MODULE, @@ -961,7 +961,7 @@ static struct crypto_alg des_alg = { static struct crypto_alg des3_ede_alg = { .cra_name = "des3_ede", - .cra_flags = CRYPTO_ALG_TYPE_CIPHER, + .cra_flags = CRYPTO_ALG_TYPE_CIPHER | CRYPTO_ALG_ENCRYPT_READ_ONCE, .cra_blocksize = DES3_EDE_BLOCK_SIZE, .cra_ctxsize = sizeof(struct des3_ede_ctx), .cra_module = THIS_MODULE, Index: linux-2.6.26-rc4/crypto/fcrypt.c =================================================================== --- linux-2.6.26-rc4.orig/crypto/fcrypt.c 2008-06-02 23:10:44.000000000 +0200 +++ linux-2.6.26-rc4/crypto/fcrypt.c 2008-06-03 16:26:28.000000000 +0200 @@ -391,7 +391,7 @@ static int fcrypt_setkey(struct crypto_t static struct crypto_alg fcrypt_alg = { .cra_name = "fcrypt", - .cra_flags = CRYPTO_ALG_TYPE_CIPHER, + .cra_flags = CRYPTO_ALG_TYPE_CIPHER | CRYPTO_ALG_ENCRYPT_READ_ONCE, .cra_blocksize = 8, .cra_ctxsize = sizeof(struct fcrypt_ctx), .cra_module = THIS_MODULE, Index: linux-2.6.26-rc4/crypto/khazad.c =================================================================== --- linux-2.6.26-rc4.orig/crypto/khazad.c 2008-06-02 23:10:44.000000000 +0200 +++ linux-2.6.26-rc4/crypto/khazad.c 2008-06-03 16:26:28.000000000 +0200 @@ -848,7 +848,7 @@ static void khazad_decrypt(struct crypto static struct crypto_alg khazad_alg = { .cra_name = "khazad", - .cra_flags = CRYPTO_ALG_TYPE_CIPHER, + .cra_flags = CRYPTO_ALG_TYPE_CIPHER | CRYPTO_ALG_ENCRYPT_READ_ONCE, .cra_blocksize = KHAZAD_BLOCK_SIZE, .cra_ctxsize = sizeof (struct khazad_ctx), .cra_alignmask = 7, Index: linux-2.6.26-rc4/crypto/seed.c =================================================================== --- linux-2.6.26-rc4.orig/crypto/seed.c 2008-06-02 22:08:59.000000000 +0200 +++ linux-2.6.26-rc4/crypto/seed.c 2008-06-03 16:26:28.000000000 +0200 @@ -444,7 +444,7 @@ static struct crypto_alg seed_alg = { .cra_name = "seed", .cra_driver_name = "seed-generic", .cra_priority = 100, - .cra_flags = CRYPTO_ALG_TYPE_CIPHER, + .cra_flags = CRYPTO_ALG_TYPE_CIPHER | CRYPTO_ALG_ENCRYPT_READ_ONCE, .cra_blocksize = SEED_BLOCK_SIZE, .cra_ctxsize = sizeof(struct seed_ctx), .cra_alignmask = 3, Index: linux-2.6.26-rc4/crypto/serpent.c =================================================================== --- linux-2.6.26-rc4.orig/crypto/serpent.c 2008-06-02 23:10:45.000000000 +0200 +++ linux-2.6.26-rc4/crypto/serpent.c 2008-06-03 16:26:28.000000000 +0200 @@ -475,7 +475,7 @@ static void serpent_decrypt(struct crypt static struct crypto_alg serpent_alg = { .cra_name = "serpent", - .cra_flags = CRYPTO_ALG_TYPE_CIPHER, + .cra_flags = CRYPTO_ALG_TYPE_CIPHER | CRYPTO_ALG_ENCRYPT_READ_ONCE, .cra_blocksize = SERPENT_BLOCK_SIZE, .cra_ctxsize = sizeof(struct serpent_ctx), .cra_alignmask = 3, @@ -543,7 +543,7 @@ static void tnepres_decrypt(struct crypt static struct crypto_alg tnepres_alg = { .cra_name = "tnepres", - .cra_flags = CRYPTO_ALG_TYPE_CIPHER, + .cra_flags = CRYPTO_ALG_TYPE_CIPHER | CRYPTO_ALG_ENCRYPT_READ_ONCE, .cra_blocksize = SERPENT_BLOCK_SIZE, .cra_ctxsize = sizeof(struct serpent_ctx), .cra_alignmask = 3, Index: linux-2.6.26-rc4/crypto/tea.c =================================================================== --- linux-2.6.26-rc4.orig/crypto/tea.c 2008-06-02 23:10:45.000000000 +0200 +++ linux-2.6.26-rc4/crypto/tea.c 2008-06-03 16:26:28.000000000 +0200 @@ -221,7 +221,7 @@ static void xeta_decrypt(struct crypto_t static struct crypto_alg tea_alg = { .cra_name = "tea", - .cra_flags = CRYPTO_ALG_TYPE_CIPHER, + .cra_flags = CRYPTO_ALG_TYPE_CIPHER | CRYPTO_ALG_ENCRYPT_READ_ONCE, .cra_blocksize = TEA_BLOCK_SIZE, .cra_ctxsize = sizeof (struct tea_ctx), .cra_alignmask = 3, @@ -253,7 +253,7 @@ static struct crypto_alg xtea_alg = { static struct crypto_alg xeta_alg = { .cra_name = "xeta", - .cra_flags = CRYPTO_ALG_TYPE_CIPHER, + .cra_flags = CRYPTO_ALG_TYPE_CIPHER | CRYPTO_ALG_ENCRYPT_READ_ONCE, .cra_blocksize = XTEA_BLOCK_SIZE, .cra_ctxsize = sizeof (struct xtea_ctx), .cra_alignmask = 3, Index: linux-2.6.26-rc4/crypto/twofish.c =================================================================== --- linux-2.6.26-rc4.orig/crypto/twofish.c 2008-06-02 23:10:45.000000000 +0200 +++ linux-2.6.26-rc4/crypto/twofish.c 2008-06-03 16:26:28.000000000 +0200 @@ -183,7 +183,7 @@ static struct crypto_alg alg = { .cra_name = "twofish", .cra_driver_name = "twofish-generic", .cra_priority = 100, - .cra_flags = CRYPTO_ALG_TYPE_CIPHER, + .cra_flags = CRYPTO_ALG_TYPE_CIPHER | CRYPTO_ALG_ENCRYPT_READ_ONCE, .cra_blocksize = TF_BLOCK_SIZE, .cra_ctxsize = sizeof(struct twofish_ctx), .cra_alignmask = 3, Index: linux-2.6.26-rc4/crypto/blkcipher.c =================================================================== --- linux-2.6.26-rc4.orig/crypto/blkcipher.c 2008-06-02 22:08:59.000000000 +0200 +++ linux-2.6.26-rc4/crypto/blkcipher.c 2008-06-03 16:26:28.000000000 +0200 @@ -640,7 +640,7 @@ struct crypto_instance *skcipher_geniv_a } inst->alg.cra_flags = CRYPTO_ALG_TYPE_GIVCIPHER | CRYPTO_ALG_GENIV; - inst->alg.cra_flags |= alg->cra_flags & CRYPTO_ALG_ASYNC; + inst->alg.cra_flags |= alg->cra_flags & (CRYPTO_ALG_ASYNC | CRYPTO_ALG_ENCRYPT_READ_ONCE); inst->alg.cra_priority = alg->cra_priority; inst->alg.cra_blocksize = alg->cra_blocksize; inst->alg.cra_alignmask = alg->cra_alignmask;