Skip to content

Commit d1c3b6b

Browse files
Eric BiggersMikulas Patocka
authored andcommitted
dm-crypt: Reimplement elephant diffuser using AES library
Simplify and optimize dm-crypt's implementation of Bitlocker's "elephant diffuser" to use the AES library instead of an "ecb(aes)" crypto_skcipher. Note: struct aes_enckey is fixed-size, so it could be embedded directly in struct iv_elephant_private. But I kept it as a separate allocation so that the size of struct crypt_config doesn't increase. The elephant diffuser is rarely used in dm-crypt. Signed-off-by: Eric Biggers <ebiggers@kernel.org> Signed-off-by: Mikulas Patocka <mpatocka@redhat.com>
1 parent 0e4c1eb commit d1c3b6b

2 files changed

Lines changed: 31 additions & 55 deletions

File tree

drivers/md/Kconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -300,6 +300,7 @@ config DM_CRYPT
300300
select CRYPTO
301301
select CRYPTO_CBC
302302
select CRYPTO_ESSIV
303+
select CRYPTO_LIB_AES
303304
select CRYPTO_LIB_MD5 # needed by lmk IV mode
304305
help
305306
This device-mapper target allows you to create a device that

drivers/md/dm-crypt.c

Lines changed: 30 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
#include <linux/ctype.h>
3333
#include <asm/page.h>
3434
#include <linux/unaligned.h>
35+
#include <crypto/aes.h>
3536
#include <crypto/hash.h>
3637
#include <crypto/md5.h>
3738
#include <crypto/skcipher.h>
@@ -133,7 +134,7 @@ struct iv_tcw_private {
133134

134135
#define ELEPHANT_MAX_KEY_SIZE 32
135136
struct iv_elephant_private {
136-
struct crypto_skcipher *tfm;
137+
struct aes_enckey *key;
137138
};
138139

139140
/*
@@ -767,8 +768,8 @@ static void crypt_iv_elephant_dtr(struct crypt_config *cc)
767768
{
768769
struct iv_elephant_private *elephant = &cc->iv_gen_private.elephant;
769770

770-
crypto_free_skcipher(elephant->tfm);
771-
elephant->tfm = NULL;
771+
kfree_sensitive(elephant->key);
772+
elephant->key = NULL;
772773
}
773774

774775
static int crypt_iv_elephant_ctr(struct crypt_config *cc, struct dm_target *ti,
@@ -777,13 +778,9 @@ static int crypt_iv_elephant_ctr(struct crypt_config *cc, struct dm_target *ti,
777778
struct iv_elephant_private *elephant = &cc->iv_gen_private.elephant;
778779
int r;
779780

780-
elephant->tfm = crypto_alloc_skcipher("ecb(aes)", 0,
781-
CRYPTO_ALG_ALLOCATES_MEMORY);
782-
if (IS_ERR(elephant->tfm)) {
783-
r = PTR_ERR(elephant->tfm);
784-
elephant->tfm = NULL;
785-
return r;
786-
}
781+
elephant->key = kmalloc_obj(*elephant->key);
782+
if (!elephant->key)
783+
return -ENOMEM;
787784

788785
r = crypt_iv_eboiv_ctr(cc, ti, NULL);
789786
if (r)
@@ -935,41 +932,28 @@ static void diffuser_b_encrypt(u32 *d, size_t n)
935932
}
936933
}
937934

938-
static int crypt_iv_elephant(struct crypt_config *cc, struct dm_crypt_request *dmreq)
935+
static void crypt_iv_elephant(struct crypt_config *cc,
936+
struct dm_crypt_request *dmreq)
939937
{
940938
struct iv_elephant_private *elephant = &cc->iv_gen_private.elephant;
941-
u8 *es, *ks, *data, *data2, *data_offset;
942-
struct skcipher_request *req;
943-
struct scatterlist *sg, *sg2, src, dst;
944-
DECLARE_CRYPTO_WAIT(wait);
945-
int i, r;
946-
947-
req = skcipher_request_alloc(elephant->tfm, GFP_NOIO);
948-
es = kzalloc(16, GFP_NOIO); /* Key for AES */
949-
ks = kzalloc(32, GFP_NOIO); /* Elephant sector key */
950-
951-
if (!req || !es || !ks) {
952-
r = -ENOMEM;
953-
goto out;
954-
}
939+
u8 *data, *data2, *data_offset;
940+
struct scatterlist *sg, *sg2;
941+
union {
942+
__le64 w[2];
943+
u8 b[16];
944+
} es;
945+
u8 ks[32] __aligned(__alignof(long)); /* Elephant sector key */
946+
int i;
955947

956-
*(__le64 *)es = cpu_to_le64(dmreq->iv_sector * cc->sector_size);
948+
es.w[0] = cpu_to_le64(dmreq->iv_sector * cc->sector_size);
949+
es.w[1] = 0;
957950

958951
/* E(Ks, e(s)) */
959-
sg_init_one(&src, es, 16);
960-
sg_init_one(&dst, ks, 16);
961-
skcipher_request_set_crypt(req, &src, &dst, 16, NULL);
962-
skcipher_request_set_callback(req, 0, crypto_req_done, &wait);
963-
r = crypto_wait_req(crypto_skcipher_encrypt(req), &wait);
964-
if (r)
965-
goto out;
952+
aes_encrypt(elephant->key, &ks[0], es.b);
966953

967954
/* E(Ks, e'(s)) */
968-
es[15] = 0x80;
969-
sg_init_one(&dst, &ks[16], 16);
970-
r = crypto_wait_req(crypto_skcipher_encrypt(req), &wait);
971-
if (r)
972-
goto out;
955+
es.b[15] = 0x80;
956+
aes_encrypt(elephant->key, &ks[16], es.b);
973957

974958
sg = crypt_get_sg_data(cc, dmreq->sg_out);
975959
data = kmap_local_page(sg_page(sg));
@@ -1001,23 +985,15 @@ static int crypt_iv_elephant(struct crypt_config *cc, struct dm_crypt_request *d
1001985
}
1002986

1003987
kunmap_local(data);
1004-
out:
1005-
kfree_sensitive(ks);
1006-
kfree_sensitive(es);
1007-
skcipher_request_free(req);
1008-
return r;
988+
memzero_explicit(ks, sizeof(ks));
989+
memzero_explicit(&es, sizeof(es));
1009990
}
1010991

1011992
static int crypt_iv_elephant_gen(struct crypt_config *cc, u8 *iv,
1012993
struct dm_crypt_request *dmreq)
1013994
{
1014-
int r;
1015-
1016-
if (bio_data_dir(dmreq->ctx->bio_in) == WRITE) {
1017-
r = crypt_iv_elephant(cc, dmreq);
1018-
if (r)
1019-
return r;
1020-
}
995+
if (bio_data_dir(dmreq->ctx->bio_in) == WRITE)
996+
crypt_iv_elephant(cc, dmreq);
1021997

1022998
return crypt_iv_eboiv_gen(cc, iv, dmreq);
1023999
}
@@ -1026,7 +1002,7 @@ static int crypt_iv_elephant_post(struct crypt_config *cc, u8 *iv,
10261002
struct dm_crypt_request *dmreq)
10271003
{
10281004
if (bio_data_dir(dmreq->ctx->bio_in) != WRITE)
1029-
return crypt_iv_elephant(cc, dmreq);
1005+
crypt_iv_elephant(cc, dmreq);
10301006

10311007
return 0;
10321008
}
@@ -1036,16 +1012,15 @@ static int crypt_iv_elephant_init(struct crypt_config *cc)
10361012
struct iv_elephant_private *elephant = &cc->iv_gen_private.elephant;
10371013
int key_offset = cc->key_size - cc->key_extra_size;
10381014

1039-
return crypto_skcipher_setkey(elephant->tfm, &cc->key[key_offset], cc->key_extra_size);
1015+
return aes_prepareenckey(elephant->key, &cc->key[key_offset], cc->key_extra_size);
10401016
}
10411017

10421018
static int crypt_iv_elephant_wipe(struct crypt_config *cc)
10431019
{
10441020
struct iv_elephant_private *elephant = &cc->iv_gen_private.elephant;
1045-
u8 key[ELEPHANT_MAX_KEY_SIZE];
10461021

1047-
memset(key, 0, cc->key_extra_size);
1048-
return crypto_skcipher_setkey(elephant->tfm, key, cc->key_extra_size);
1022+
memzero_explicit(elephant->key, sizeof(*elephant->key));
1023+
return 0;
10491024
}
10501025

10511026
static const struct crypt_iv_operations crypt_iv_plain_ops = {

0 commit comments

Comments
 (0)