Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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>

authored by

Eric Biggers and committed by
Mikulas Patocka
d1c3b6b8 0e4c1eb5

+31 -55
+1
drivers/md/Kconfig
··· 300 300 select CRYPTO 301 301 select CRYPTO_CBC 302 302 select CRYPTO_ESSIV 303 + select CRYPTO_LIB_AES 303 304 select CRYPTO_LIB_MD5 # needed by lmk IV mode 304 305 help 305 306 This device-mapper target allows you to create a device that
+30 -55
drivers/md/dm-crypt.c
··· 32 32 #include <linux/ctype.h> 33 33 #include <asm/page.h> 34 34 #include <linux/unaligned.h> 35 + #include <crypto/aes.h> 35 36 #include <crypto/hash.h> 36 37 #include <crypto/md5.h> 37 38 #include <crypto/skcipher.h> ··· 134 133 135 134 #define ELEPHANT_MAX_KEY_SIZE 32 136 135 struct iv_elephant_private { 137 - struct crypto_skcipher *tfm; 136 + struct aes_enckey *key; 138 137 }; 139 138 140 139 /* ··· 768 767 { 769 768 struct iv_elephant_private *elephant = &cc->iv_gen_private.elephant; 770 769 771 - crypto_free_skcipher(elephant->tfm); 772 - elephant->tfm = NULL; 770 + kfree_sensitive(elephant->key); 771 + elephant->key = NULL; 773 772 } 774 773 775 774 static int crypt_iv_elephant_ctr(struct crypt_config *cc, struct dm_target *ti, ··· 778 777 struct iv_elephant_private *elephant = &cc->iv_gen_private.elephant; 779 778 int r; 780 779 781 - elephant->tfm = crypto_alloc_skcipher("ecb(aes)", 0, 782 - CRYPTO_ALG_ALLOCATES_MEMORY); 783 - if (IS_ERR(elephant->tfm)) { 784 - r = PTR_ERR(elephant->tfm); 785 - elephant->tfm = NULL; 786 - return r; 787 - } 780 + elephant->key = kmalloc_obj(*elephant->key); 781 + if (!elephant->key) 782 + return -ENOMEM; 788 783 789 784 r = crypt_iv_eboiv_ctr(cc, ti, NULL); 790 785 if (r) ··· 932 935 } 933 936 } 934 937 935 - static int crypt_iv_elephant(struct crypt_config *cc, struct dm_crypt_request *dmreq) 938 + static void crypt_iv_elephant(struct crypt_config *cc, 939 + struct dm_crypt_request *dmreq) 936 940 { 937 941 struct iv_elephant_private *elephant = &cc->iv_gen_private.elephant; 938 - u8 *es, *ks, *data, *data2, *data_offset; 939 - struct skcipher_request *req; 940 - struct scatterlist *sg, *sg2, src, dst; 941 - DECLARE_CRYPTO_WAIT(wait); 942 - int i, r; 942 + u8 *data, *data2, *data_offset; 943 + struct scatterlist *sg, *sg2; 944 + union { 945 + __le64 w[2]; 946 + u8 b[16]; 947 + } es; 948 + u8 ks[32] __aligned(__alignof(long)); /* Elephant sector key */ 949 + int i; 943 950 944 - req = skcipher_request_alloc(elephant->tfm, GFP_NOIO); 945 - es = kzalloc(16, GFP_NOIO); /* Key for AES */ 946 - ks = kzalloc(32, GFP_NOIO); /* Elephant sector key */ 947 - 948 - if (!req || !es || !ks) { 949 - r = -ENOMEM; 950 - goto out; 951 - } 952 - 953 - *(__le64 *)es = cpu_to_le64(dmreq->iv_sector * cc->sector_size); 951 + es.w[0] = cpu_to_le64(dmreq->iv_sector * cc->sector_size); 952 + es.w[1] = 0; 954 953 955 954 /* E(Ks, e(s)) */ 956 - sg_init_one(&src, es, 16); 957 - sg_init_one(&dst, ks, 16); 958 - skcipher_request_set_crypt(req, &src, &dst, 16, NULL); 959 - skcipher_request_set_callback(req, 0, crypto_req_done, &wait); 960 - r = crypto_wait_req(crypto_skcipher_encrypt(req), &wait); 961 - if (r) 962 - goto out; 955 + aes_encrypt(elephant->key, &ks[0], es.b); 963 956 964 957 /* E(Ks, e'(s)) */ 965 - es[15] = 0x80; 966 - sg_init_one(&dst, &ks[16], 16); 967 - r = crypto_wait_req(crypto_skcipher_encrypt(req), &wait); 968 - if (r) 969 - goto out; 958 + es.b[15] = 0x80; 959 + aes_encrypt(elephant->key, &ks[16], es.b); 970 960 971 961 sg = crypt_get_sg_data(cc, dmreq->sg_out); 972 962 data = kmap_local_page(sg_page(sg)); ··· 985 1001 } 986 1002 987 1003 kunmap_local(data); 988 - out: 989 - kfree_sensitive(ks); 990 - kfree_sensitive(es); 991 - skcipher_request_free(req); 992 - return r; 1004 + memzero_explicit(ks, sizeof(ks)); 1005 + memzero_explicit(&es, sizeof(es)); 993 1006 } 994 1007 995 1008 static int crypt_iv_elephant_gen(struct crypt_config *cc, u8 *iv, 996 1009 struct dm_crypt_request *dmreq) 997 1010 { 998 - int r; 999 - 1000 - if (bio_data_dir(dmreq->ctx->bio_in) == WRITE) { 1001 - r = crypt_iv_elephant(cc, dmreq); 1002 - if (r) 1003 - return r; 1004 - } 1011 + if (bio_data_dir(dmreq->ctx->bio_in) == WRITE) 1012 + crypt_iv_elephant(cc, dmreq); 1005 1013 1006 1014 return crypt_iv_eboiv_gen(cc, iv, dmreq); 1007 1015 } ··· 1002 1026 struct dm_crypt_request *dmreq) 1003 1027 { 1004 1028 if (bio_data_dir(dmreq->ctx->bio_in) != WRITE) 1005 - return crypt_iv_elephant(cc, dmreq); 1029 + crypt_iv_elephant(cc, dmreq); 1006 1030 1007 1031 return 0; 1008 1032 } ··· 1012 1036 struct iv_elephant_private *elephant = &cc->iv_gen_private.elephant; 1013 1037 int key_offset = cc->key_size - cc->key_extra_size; 1014 1038 1015 - return crypto_skcipher_setkey(elephant->tfm, &cc->key[key_offset], cc->key_extra_size); 1039 + return aes_prepareenckey(elephant->key, &cc->key[key_offset], cc->key_extra_size); 1016 1040 } 1017 1041 1018 1042 static int crypt_iv_elephant_wipe(struct crypt_config *cc) 1019 1043 { 1020 1044 struct iv_elephant_private *elephant = &cc->iv_gen_private.elephant; 1021 - u8 key[ELEPHANT_MAX_KEY_SIZE]; 1022 1045 1023 - memset(key, 0, cc->key_extra_size); 1024 - return crypto_skcipher_setkey(elephant->tfm, key, cc->key_extra_size); 1046 + memzero_explicit(elephant->key, sizeof(*elephant->key)); 1047 + return 0; 1025 1048 } 1026 1049 1027 1050 static const struct crypt_iv_operations crypt_iv_plain_ops = {