Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
dm crypt: switch to EBOIV crypto API template
Replace the explicit EBOIV handling in the dm-crypt driver with calls
into the crypto API, which now possesses the capability to perform
this processing within the crypto subsystem.

Signed-off-by: Gilad Ben-Yossef <gilad@benyossef.com>
  • Loading branch information
gby authored and intel-lab-lkp committed Oct 26, 2020
1 parent 1ff3f43 commit 740a3c7
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 42 deletions.
1 change: 1 addition & 0 deletions drivers/md/Kconfig
Expand Up @@ -273,6 +273,7 @@ config DM_CRYPT
select CRYPTO
select CRYPTO_CBC
select CRYPTO_ESSIV
select CRYPTO_EBOIV
help
This device-mapper target allows you to create a device that
transparently encrypts the data on it. You'll need to activate
Expand Down
61 changes: 19 additions & 42 deletions drivers/md/dm-crypt.c
Expand Up @@ -716,47 +716,18 @@ static int crypt_iv_random_gen(struct crypt_config *cc, u8 *iv,
return 0;
}

static int crypt_iv_eboiv_ctr(struct crypt_config *cc, struct dm_target *ti,
const char *opts)
{
if (crypt_integrity_aead(cc)) {
ti->error = "AEAD transforms not supported for EBOIV";
return -EINVAL;
}

if (crypto_skcipher_blocksize(any_tfm(cc)) != cc->iv_size) {
ti->error = "Block size of EBOIV cipher does "
"not match IV size of block cipher";
return -EINVAL;
}

return 0;
}

static int crypt_iv_eboiv_gen(struct crypt_config *cc, u8 *iv,
struct dm_crypt_request *dmreq)
{
u8 buf[MAX_CIPHER_BLOCKSIZE] __aligned(__alignof__(__le64));
struct skcipher_request *req;
struct scatterlist src, dst;
struct crypto_wait wait;
int err;

req = skcipher_request_alloc(any_tfm(cc), GFP_NOIO);
if (!req)
return -ENOMEM;

memset(buf, 0, cc->iv_size);
*(__le64 *)buf = cpu_to_le64(dmreq->iv_sector * cc->sector_size);

sg_init_one(&src, page_address(ZERO_PAGE(0)), cc->iv_size);
sg_init_one(&dst, iv, cc->iv_size);
skcipher_request_set_crypt(req, &src, &dst, cc->iv_size, buf);
skcipher_request_set_callback(req, 0, crypto_req_done, &wait);
err = crypto_wait_req(crypto_skcipher_encrypt(req), &wait);
skcipher_request_free(req);
/*
* ESSIV encryption of the IV is handled by the crypto API,
* so compute and pass the sector offset here.
*/
memset(iv, 0, cc->iv_size);
*(__le64 *)iv = cpu_to_le64(dmreq->iv_sector * cc->sector_size);

return err;
return 0;
}

static void crypt_iv_elephant_dtr(struct crypt_config *cc)
Expand All @@ -777,13 +748,9 @@ static int crypt_iv_elephant_ctr(struct crypt_config *cc, struct dm_target *ti,
if (IS_ERR(elephant->tfm)) {
r = PTR_ERR(elephant->tfm);
elephant->tfm = NULL;
return r;
}

r = crypt_iv_eboiv_ctr(cc, ti, NULL);
if (r)
crypt_iv_elephant_dtr(cc);
return r;
return 0;
}

static void diffuser_disk_to_cpu(u32 *d, size_t n)
Expand Down Expand Up @@ -1092,7 +1059,6 @@ static struct crypt_iv_operations crypt_iv_random_ops = {
};

static struct crypt_iv_operations crypt_iv_eboiv_ops = {
.ctr = crypt_iv_eboiv_ctr,
.generator = crypt_iv_eboiv_gen
};

Expand Down Expand Up @@ -2739,6 +2705,15 @@ static int crypt_ctr_cipher_new(struct dm_target *ti, char *cipher_in, char *key
cipher_api = buf;
}

if (*ivmode && (!strcmp(*ivmode, "eboiv") || !strcmp(*ivmode, "elephant"))) {
ret = snprintf(buf, CRYPTO_MAX_ALG_NAME, "eboiv(%s)", cipher_api);
if (ret < 0 || ret >= CRYPTO_MAX_ALG_NAME) {
ti->error = "Cannot allocate cipher string";
return -ENOMEM;
}
cipher_api = buf;
}

cc->key_parts = cc->tfms_count;

/* Allocate cipher */
Expand Down Expand Up @@ -2817,6 +2792,8 @@ static int crypt_ctr_cipher_old(struct dm_target *ti, char *cipher_in, char *key
}
ret = snprintf(cipher_api, CRYPTO_MAX_ALG_NAME,
"essiv(%s(%s),%s)", chainmode, cipher, *ivopts);
} else if (*ivmode && (!strcmp(*ivmode, "eboiv") || !strcmp(*ivmode, "elephant"))) {
ret = snprintf(cipher_api, CRYPTO_MAX_ALG_NAME, "eboiv(%s(%s))", chainmode, cipher);
} else {
ret = snprintf(cipher_api, CRYPTO_MAX_ALG_NAME,
"%s(%s)", chainmode, cipher);
Expand Down

0 comments on commit 740a3c7

Please sign in to comment.