Commit 19a1852e authored by Milan Broz's avatar Milan Broz

Support sector size option even for plain devices.

parent c6d4ebd8
......@@ -46,6 +46,7 @@
#define SECTOR_SHIFT 9
#define SECTOR_SIZE (1 << SECTOR_SHIFT)
#define MAX_SECTOR_SIZE 4096 /* min page size among all platforms */
#define DEFAULT_DISK_ALIGNMENT 1048576 /* 1MiB */
#define DEFAULT_MEM_ALIGNMENT 4096
#define MAX_ERROR_LENGTH 512
......
......@@ -356,6 +356,7 @@ struct crypt_params_plain {
uint64_t offset; /**< offset in sectors */
uint64_t skip; /**< IV offset / initialization sector */
uint64_t size; /**< size of mapped device or @e 0 for autodetection */
uint32_t sector_size; /**< sector size in bytes (@e 0 means 512 for compatibility) */
};
/**
......@@ -1214,7 +1215,7 @@ const char *crypt_get_uuid(struct crypt_device *cd);
const char *crypt_get_device_name(struct crypt_device *cd);
/**
* Get device offset in sectors where real data starts (on underlying device).
* Get device offset in 512-bytes sectors where real data starts (on underlying device).
*
* @param cd crypt device handle
*
......@@ -1224,7 +1225,7 @@ const char *crypt_get_device_name(struct crypt_device *cd);
uint64_t crypt_get_data_offset(struct crypt_device *cd);
/**
* Get IV offset in sectors (skip).
* Get IV offset in 512-bytes sectors (skip).
*
* @param cd crypt device handle
*
......
......@@ -587,7 +587,7 @@ static int crypt_check_data_device_size(struct crypt_device *cd)
int r;
uint64_t size, size_min;
/* Check data device size, require at least one sector */
/* Check data device size, require at least header or one sector */
size_min = crypt_get_data_offset(cd) << SECTOR_SHIFT ?: SECTOR_SIZE;
r = device_size(cd->device, &size);
......@@ -1065,6 +1065,7 @@ static int _init_by_name_crypt(struct crypt_device *cd, const char *name)
cd->u.plain.hdr.hash = NULL; /* no way to get this */
cd->u.plain.hdr.offset = dmd.u.crypt.offset;
cd->u.plain.hdr.skip = dmd.u.crypt.iv_offset;
cd->u.plain.hdr.sector_size = dmd.u.crypt.sector_size;
cd->u.plain.key_size = dmd.u.crypt.vk->keylength;
cd->u.plain.cipher = strdup(cipher);
cd->u.plain.cipher_mode = strdup(cipher_mode);
......@@ -1311,6 +1312,8 @@ static int _crypt_format_plain(struct crypt_device *cd,
size_t volume_key_size,
struct crypt_params_plain *params)
{
unsigned int sector_size = params ? params->sector_size : SECTOR_SIZE;
if (!cipher || !cipher_mode) {
log_err(cd, _("Invalid plain crypt parameters.\n"));
return -EINVAL;
......@@ -1326,6 +1329,16 @@ static int _crypt_format_plain(struct crypt_device *cd,
return -EINVAL;
}
/* For compatibility with old params structure */
if (!sector_size)
sector_size = SECTOR_SIZE;
if (sector_size < SECTOR_SIZE || sector_size > MAX_SECTOR_SIZE ||
(sector_size & (sector_size - 1))) {
log_err(cd, _("Unsupported encryption sector size.\n"));
return -EINVAL;
}
if (!(cd->type = strdup(CRYPT_PLAIN)))
return -ENOMEM;
......@@ -1344,6 +1357,7 @@ static int _crypt_format_plain(struct crypt_device *cd,
cd->u.plain.hdr.offset = params ? params->offset : 0;
cd->u.plain.hdr.skip = params ? params->skip : 0;
cd->u.plain.hdr.size = params ? params->size : 0;
cd->u.plain.hdr.sector_size = sector_size;
if (!cd->u.plain.cipher || !cd->u.plain.cipher_mode)
return -ENOMEM;
......@@ -1459,7 +1473,8 @@ static int _crypt_format_luks2(struct crypt_device *cd,
return -EINVAL;
}
if (sector_size < 512 || sector_size > 4096 || (sector_size & (sector_size - 1))) {
if (sector_size < SECTOR_SIZE || sector_size > MAX_SECTOR_SIZE ||
(sector_size & (sector_size - 1))) {
log_err(cd, _("Unsupported encryption sector size.\n"));
return -EINVAL;
}
......@@ -3600,6 +3615,9 @@ int crypt_get_sector_size(struct crypt_device *cd)
if (!cd)
return SECTOR_SIZE;
if (isPLAIN(cd->type))
return cd->u.plain.hdr.sector_size;
if (isINTEGRITY(cd->type))
return cd->u.integrity.params.sector_size;
......
......@@ -110,7 +110,7 @@ Reports the status for the mapping <name>.
.IP
Resizes an active mapping <name>.
If \-\-size (in sectors) is not specified, the size is computed
If \-\-size (in 512-bytes sectors) is not specified, the size is computed
from the underlying device. For LUKS it is the size of the
underlying device without the area reserved for LUKS header
(see data payload offset in \fBluksDump\fR command).
......@@ -147,8 +147,8 @@ The following are valid plain device type actions:
Opens (creates a mapping with) <name> backed by device <device>.
\fB<options>\fR can be [\-\-hash, \-\-cipher, \-\-verify-passphrase,
\-\-key-file, \-\-keyfile-offset, \-\-key-size, \-\-offset, \-\-skip, \-\-size,
\-\-readonly, \-\-shared, \-\-allow\-discards]
\-\-sector\-size, \-\-key-file, \-\-keyfile-offset, \-\-key-size,
\-\-offset, \-\-skip, \-\-size, \-\-readonly, \-\-shared, \-\-allow\-discards]
Example: 'cryptsetup open \-\-type plain /dev/sda10 e1' maps the raw
encrypted device /dev/sda10 to the mapped (decrypted) device
......
......@@ -83,7 +83,7 @@ static const char *opt_integrity = NULL; /* none */
static int opt_integrity_nojournal = 0;
static int opt_integrity_no_wipe = 0;
static const char *opt_key_description = NULL;
static int opt_sector_size = 512;
static int opt_sector_size = SECTOR_SIZE;
static int opt_persistent = 0;
static const char *opt_label = NULL;
static const char *opt_subsystem = NULL;
......@@ -166,6 +166,7 @@ static int action_open_plain(void)
.skip = opt_skip,
.offset = opt_offset,
.size = opt_size,
.sector_size = opt_sector_size,
};
char *password = NULL;
size_t passwordLen, key_size_max;
......@@ -954,7 +955,7 @@ static int action_luksFormat(void)
else
luks_version = 1;
if (opt_sector_size > 512 && luks_version == 1) {
if (opt_sector_size > SECTOR_SIZE && luks_version == 1) {
log_err(_("Unsupported encryption sector size.\n"));
return -EINVAL;
}
......@@ -2357,8 +2358,14 @@ int main(int argc, const char **argv)
_("PBKDF forced iterations cannot be combined with iteration time option.\n"),
poptGetInvocationName(popt_context));
if ((opt_sector_size != 512 && strcmp(aname, "luksFormat")) || opt_sector_size < 512
|| opt_sector_size > 4096 || (opt_sector_size & (opt_sector_size - 1)))
if (opt_sector_size != SECTOR_SIZE && strcmp(aname, "luksFormat") &&
(strcmp(aname, "open") || strcmp(opt_type, "plain")))
usage(popt_context, EXIT_FAILURE,
_("Sector size option is not supported for this command.\n"),
poptGetInvocationName(popt_context));
if (opt_sector_size < SECTOR_SIZE || opt_sector_size > MAX_SECTOR_SIZE ||
(opt_sector_size & (opt_sector_size - 1)))
usage(popt_context, EXIT_FAILURE,
_("Unsupported encryption sector size.\n"),
poptGetInvocationName(popt_context));
......
......@@ -49,6 +49,7 @@
#define CONST_CAST(x) (x)(uintptr_t)
#define DEFAULT_CIPHER(type) (DEFAULT_##type##_CIPHER "-" DEFAULT_##type##_MODE)
#define SECTOR_SIZE 512
#define MAX_SECTOR_SIZE 4096
#define ROUND_SECTOR(x) (((x) + SECTOR_SIZE - 1) / SECTOR_SIZE)
#define DEFAULT_WIPE_BLOCK 1048576 /* 1 MiB */
......
......@@ -46,6 +46,14 @@ format() # format
[ $? -ne 0 ] && fail "Keyslot removal failed."
}
check_sector_size() # $1 expected sector size
{
$CRYPTSETUP status $DEV_NAME | grep "sector size" | grep -q $1 || fail
if [ $S -gt 512 ]; then
dmsetup table $DEV_NAME | grep -q "sector_size:$1" || fail
fi
}
if [ $(id -u) != 0 ]; then
echo "WARNING: You must be root to run this test, test skipped."
exit 0
......@@ -103,4 +111,33 @@ else
$CRYPTSETUP close $DEV_NAME || fail
fi
echo "[3] Kernel dmcrypt sector size options"
echo -e "$PWD1" | $CRYPTSETUP open --type plain $DEV $DEV_NAME --sector-size 4096 >/dev/null 2>&1
if [ $? -ne 0 ] ; then
echo "TEST SKIPPED: dmcrypt sector-size option not available"
else
$CRYPTSETUP close $DEV_NAME || fail
echo -n "PLAIN sector size:"
echo -e "$PWD1" | $CRYPTSETUP open --type plain $DEV $DEV_NAME --sector-size 1234 >/dev/null 2>&1 && fail
for S in 512 1024 2048 4096; do
echo -n "[$S]"
echo -e "$PWD1" | $CRYPTSETUP open --type plain $DEV $DEV_NAME --sector-size $S || fail
check_sector_size $S
$CRYPTSETUP close $DEV_NAME || fail
done
echo
echo -n "LUKS2 sector size:"
echo -e "$PWD1" | $CRYPTSETUP luksFormat --type luks2 -$DEV --sector-size 1234 >/dev/null 2>&1 && fail
for S in 512 1024 2048 4096; do
echo -n "[$S]"
echo -e "$PWD1" | $CRYPTSETUP luksFormat --type luks2 --pbkdf pbkdf2 --pbkdf-force-iterations 1000 $DEV --sector-size $S || fail
echo -e "$PWD1" | $CRYPTSETUP open $DEV $DEV_NAME || fail
check_sector_size $S
$CRYPTSETUP close $DEV_NAME || fail
done
echo
fi
cleanup
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment