diff options
| -rw-r--r-- | drivers/md/Kconfig | 1 | ||||
| -rw-r--r-- | drivers/md/dm-crypt.c | 76 |
2 files changed, 22 insertions, 55 deletions
diff --git a/drivers/md/Kconfig b/drivers/md/Kconfig index 104aa5355090..dcd232a2ca24 100644 --- a/drivers/md/Kconfig +++ b/drivers/md/Kconfig @@ -299,6 +299,7 @@ config DM_CRYPT select CRYPTO select CRYPTO_CBC select CRYPTO_ESSIV + select CRYPTO_LIB_MD5 # needed by lmk IV mode help This device-mapper target allows you to create a device that transparently encrypts the data on it. You'll need to activate diff --git a/drivers/md/dm-crypt.c b/drivers/md/dm-crypt.c index 5ef43231fe77..04a553529dc2 100644 --- a/drivers/md/dm-crypt.c +++ b/drivers/md/dm-crypt.c @@ -21,6 +21,7 @@ #include <linux/mempool.h> #include <linux/slab.h> #include <linux/crypto.h> +#include <linux/fips.h> #include <linux/workqueue.h> #include <linux/kthread.h> #include <linux/backing-dev.h> @@ -120,7 +121,6 @@ struct iv_benbi_private { #define LMK_SEED_SIZE 64 /* hash + 0 */ struct iv_lmk_private { - struct crypto_shash *hash_tfm; u8 *seed; }; @@ -465,10 +465,6 @@ static void crypt_iv_lmk_dtr(struct crypt_config *cc) { struct iv_lmk_private *lmk = &cc->iv_gen_private.lmk; - if (lmk->hash_tfm && !IS_ERR(lmk->hash_tfm)) - crypto_free_shash(lmk->hash_tfm); - lmk->hash_tfm = NULL; - kfree_sensitive(lmk->seed); lmk->seed = NULL; } @@ -483,11 +479,10 @@ static int crypt_iv_lmk_ctr(struct crypt_config *cc, struct dm_target *ti, return -EINVAL; } - lmk->hash_tfm = crypto_alloc_shash("md5", 0, - CRYPTO_ALG_ALLOCATES_MEMORY); - if (IS_ERR(lmk->hash_tfm)) { - ti->error = "Error initializing LMK hash"; - return PTR_ERR(lmk->hash_tfm); + if (fips_enabled) { + ti->error = "LMK support is disabled due to FIPS"; + /* ... because it uses MD5. */ + return -EINVAL; } /* No seed in LMK version 2 */ @@ -498,7 +493,6 @@ static int crypt_iv_lmk_ctr(struct crypt_config *cc, struct dm_target *ti, lmk->seed = kzalloc(LMK_SEED_SIZE, GFP_KERNEL); if (!lmk->seed) { - crypt_iv_lmk_dtr(cc); ti->error = "Error kmallocing seed storage in LMK"; return -ENOMEM; } @@ -514,7 +508,7 @@ static int crypt_iv_lmk_init(struct crypt_config *cc) /* LMK seed is on the position of LMK_KEYS + 1 key */ if (lmk->seed) memcpy(lmk->seed, cc->key + (cc->tfms_count * subkey_size), - crypto_shash_digestsize(lmk->hash_tfm)); + MD5_DIGEST_SIZE); return 0; } @@ -529,55 +523,31 @@ static int crypt_iv_lmk_wipe(struct crypt_config *cc) return 0; } -static int crypt_iv_lmk_one(struct crypt_config *cc, u8 *iv, - struct dm_crypt_request *dmreq, - u8 *data) +static void crypt_iv_lmk_one(struct crypt_config *cc, u8 *iv, + struct dm_crypt_request *dmreq, u8 *data) { struct iv_lmk_private *lmk = &cc->iv_gen_private.lmk; - SHASH_DESC_ON_STACK(desc, lmk->hash_tfm); - union { - struct md5_state md5state; - u8 state[CRYPTO_MD5_STATESIZE]; - } u; + struct md5_ctx ctx; __le32 buf[4]; - int i, r; - desc->tfm = lmk->hash_tfm; - - r = crypto_shash_init(desc); - if (r) - return r; + md5_init(&ctx); - if (lmk->seed) { - r = crypto_shash_update(desc, lmk->seed, LMK_SEED_SIZE); - if (r) - return r; - } + if (lmk->seed) + md5_update(&ctx, lmk->seed, LMK_SEED_SIZE); /* Sector is always 512B, block size 16, add data of blocks 1-31 */ - r = crypto_shash_update(desc, data + 16, 16 * 31); - if (r) - return r; + md5_update(&ctx, data + 16, 16 * 31); /* Sector is cropped to 56 bits here */ buf[0] = cpu_to_le32(dmreq->iv_sector & 0xFFFFFFFF); buf[1] = cpu_to_le32((((u64)dmreq->iv_sector >> 32) & 0x00FFFFFF) | 0x80000000); buf[2] = cpu_to_le32(4024); buf[3] = 0; - r = crypto_shash_update(desc, (u8 *)buf, sizeof(buf)); - if (r) - return r; + md5_update(&ctx, (u8 *)buf, sizeof(buf)); /* No MD5 padding here */ - r = crypto_shash_export(desc, &u.md5state); - if (r) - return r; - - for (i = 0; i < MD5_HASH_WORDS; i++) - __cpu_to_le32s(&u.md5state.hash[i]); - memcpy(iv, &u.md5state.hash, cc->iv_size); - - return 0; + cpu_to_le32_array(ctx.state.h, ARRAY_SIZE(ctx.state.h)); + memcpy(iv, ctx.state.h, cc->iv_size); } static int crypt_iv_lmk_gen(struct crypt_config *cc, u8 *iv, @@ -585,17 +555,15 @@ static int crypt_iv_lmk_gen(struct crypt_config *cc, u8 *iv, { struct scatterlist *sg; u8 *src; - int r = 0; if (bio_data_dir(dmreq->ctx->bio_in) == WRITE) { sg = crypt_get_sg_data(cc, dmreq->sg_in); src = kmap_local_page(sg_page(sg)); - r = crypt_iv_lmk_one(cc, iv, dmreq, src + sg->offset); + crypt_iv_lmk_one(cc, iv, dmreq, src + sg->offset); kunmap_local(src); } else memset(iv, 0, cc->iv_size); - - return r; + return 0; } static int crypt_iv_lmk_post(struct crypt_config *cc, u8 *iv, @@ -603,21 +571,19 @@ static int crypt_iv_lmk_post(struct crypt_config *cc, u8 *iv, { struct scatterlist *sg; u8 *dst; - int r; if (bio_data_dir(dmreq->ctx->bio_in) == WRITE) return 0; sg = crypt_get_sg_data(cc, dmreq->sg_out); dst = kmap_local_page(sg_page(sg)); - r = crypt_iv_lmk_one(cc, iv, dmreq, dst + sg->offset); + crypt_iv_lmk_one(cc, iv, dmreq, dst + sg->offset); /* Tweak the first block of plaintext sector */ - if (!r) - crypto_xor(dst + sg->offset, iv, cc->iv_size); + crypto_xor(dst + sg->offset, iv, cc->iv_size); kunmap_local(dst); - return r; + return 0; } static void crypt_iv_tcw_dtr(struct crypt_config *cc) |
