Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6cb50c7e authored by qctecmdr's avatar qctecmdr Committed by Gerrit - the friendly Code Review server
Browse files

Merge "md: dm-default-key: Fix IV with set_dun flag defined"

parents 9b50857e 4ae1681b
Loading
Loading
Loading
Loading
+45 −18
Original line number Diff line number Diff line
@@ -81,7 +81,8 @@ static void default_key_dtr(struct dm_target *ti)
}

static int default_key_ctr_optional(struct dm_target *ti,
				    unsigned int argc, char **argv)
				    unsigned int argc, char **argv,
				    bool is_legacy)
{
	struct default_key_c *dkc = ti->private;
	struct dm_arg_set as;
@@ -121,7 +122,7 @@ static int default_key_ctr_optional(struct dm_target *ti,
			iv_large_sectors = true;
		} else if (!strcmp(opt_string, "wrappedkey_v0")) {
			dkc->is_hw_wrapped = true;
		} else if (!strcmp(opt_string, "set_dun")) {
		} else if (!strcmp(opt_string, "set_dun") && is_legacy) {
			dkc->set_dun = true;
		} else {
			ti->error = "Invalid feature arguments";
@@ -166,7 +167,7 @@ static void default_key_adjust_sector_size_and_iv(char **argv,
		     !strcmp((*dkc)->dev->bdev->bd_disk->disk_name, "mmcblk0")))
			(*dkc)->sector_size = SECTOR_SIZE;

		if (dev->bdev->bd_part)
		if (dev->bdev->bd_part && !(*dkc)->set_dun)
			(*dkc)->iv_offset += dev->bdev->bd_part->start_sect;
	}
}
@@ -189,22 +190,31 @@ static int default_key_ctr(struct dm_target *ti, unsigned int argc, char **argv)
	unsigned long long tmpll;
	char dummy;
	int err;
	int __argc;
	char *_argv[10];
	bool is_legacy = false;

	if (argc >= 4 && !strcmp(argv[0], "AES-256-XTS")) {
		argc = 0;
		_argv[argc++] = "aes-xts-plain64";
		_argv[argc++] = argv[1];
		_argv[argc++] = "0";
		_argv[argc++] = argv[2];
		_argv[argc++] = argv[3];
		_argv[argc++] = "3";
		_argv[argc++] = "allow_discards";
		_argv[argc++] = "sector_size:4096";
		_argv[argc++] = "iv_large_sectors";
		_argv[argc] = NULL;
		__argc = 0;
		_argv[__argc++] = "aes-xts-plain64";
		_argv[__argc++] = argv[1];
		_argv[__argc++] = "0";
		_argv[__argc++] = argv[2];
		_argv[__argc++] = argv[3];
		if (argc > 4)
			_argv[__argc++] = "4";
		else
			_argv[__argc++] = "3";

		_argv[__argc++] = "allow_discards";
		_argv[__argc++] = "sector_size:4096";
		_argv[__argc++] = "iv_large_sectors";
		if (argc > 4)
			_argv[__argc++] = argv[5];

		_argv[__argc] = NULL;
		argv = _argv;
		argc = __argc;
		is_legacy = true;
	}

@@ -276,7 +286,8 @@ static int default_key_ctr(struct dm_target *ti, unsigned int argc, char **argv)
	/* optional arguments */
	dkc->sector_size = SECTOR_SIZE;
	if (argc > 5) {
		err = default_key_ctr_optional(ti, argc - 5, &argv[5]);
		err = default_key_ctr_optional(ti, argc - 5, &argv[5],
					       is_legacy);
		if (err)
			goto bad;
	}
@@ -325,6 +336,13 @@ static int default_key_ctr(struct dm_target *ti, unsigned int argc, char **argv)
	return err;
}

static void default_key_map_dun(struct bio *bio, u64 *dun)
{
	dun[0] += 1;
	memcpy(bio->bi_crypt_context->bc_dun, dun,
	       sizeof(bio->bi_crypt_context->bc_dun));
	bio->bi_crypt_context->is_ext4 = false;
}
static int default_key_map(struct dm_target *ti, struct bio *bio)
{
	const struct default_key_c *dkc = ti->private;
@@ -349,14 +367,15 @@ static int default_key_map(struct dm_target *ti, struct bio *bio)
	 * file's contents), or if it doesn't have any data (e.g. if it's a
	 * DISCARD request), there's nothing more to do.
	 */
	if (bio_should_skip_dm_default_key(bio) || !bio_has_data(bio))
	if ((bio_should_skip_dm_default_key(bio) && !dkc->set_dun) ||
	    !bio_has_data(bio))
		return DM_MAPIO_REMAPPED;

	/*
	 * Else, dm-default-key needs to set this bio's encryption context.
	 * It must not already have one.
	 */
	if (WARN_ON_ONCE(bio_has_crypt_ctx(bio)))
	if (WARN_ON_ONCE(bio_has_crypt_ctx(bio) && !dkc->set_dun))
		return DM_MAPIO_KILL;

	/* Calculate the DUN and enforce data-unit (crypto sector) alignment. */
@@ -372,8 +391,12 @@ static int default_key_map(struct dm_target *ti, struct bio *bio)
	if (WARN_ON_ONCE(dun[0] > dkc->max_dun))
		return DM_MAPIO_KILL;

	if (!bio_has_crypt_ctx(bio))
		bio_crypt_set_ctx(bio, &dkc->key, dun, GFP_NOIO);

	if (dkc->set_dun)
		default_key_map_dun(bio, dun);

	return DM_MAPIO_REMAPPED;
}

@@ -400,6 +423,8 @@ static void default_key_status(struct dm_target *ti, status_type_t type,
			num_feature_args += 2;
		if (dkc->is_hw_wrapped)
			num_feature_args += 1;
		if (dkc->set_dun)
			num_feature_args += 1;
		if (num_feature_args != 0) {
			DMEMIT(" %d", num_feature_args);
			if (ti->num_discard_bios)
@@ -410,6 +435,8 @@ static void default_key_status(struct dm_target *ti, status_type_t type,
			}
			if (dkc->is_hw_wrapped)
				DMEMIT(" wrappedkey_v0");
			if (dkc->set_dun)
				DMEMIT(" set_dun");
		}
		break;
	}