Commit b42d183b authored by Milan Broz's avatar Milan Broz

Create LUKS header file in luksFormat if it does not exist.

parent e1ed664a
......@@ -73,7 +73,7 @@ AC_SUBST(UUID_LIBS, $LIBS)
LIBS=$saved_LIBS
AC_SEARCH_LIBS([clock_gettime],[rt posix4])
AC_CHECK_FUNCS([posix_memalign clock_gettime])
AC_CHECK_FUNCS([posix_memalign clock_gettime posix_fallocate])
if test "x$enable_largefile" = "xno" ; then
AC_MSG_ERROR([Building with --disable-largefile is not supported, it can cause data corruption.])
......
......@@ -104,6 +104,7 @@ int device_is_identical(struct device *device1, struct device *device2);
int device_is_rotational(struct device *device);
size_t device_alignment(struct device *device);
int device_direct_io(const struct device *device);
int device_fallocate(struct device *device, uint64_t size);
int device_open_locked(struct device *device, int flags);
int device_read_lock(struct crypt_device *cd, struct device *device);
......
......@@ -102,7 +102,7 @@ size_t LUKS_keyslots_offset(const struct luks_phdr *hdr)
return hdr->keyblock[sorted_areas[0]].keyMaterialOffset;
}
static int LUKS_check_device_size(struct crypt_device *ctx, const struct luks_phdr *hdr)
static int LUKS_check_device_size(struct crypt_device *ctx, const struct luks_phdr *hdr, int falloc)
{
struct device *device = crypt_metadata_device(ctx);
uint64_t dev_sectors, hdr_sectors;
......@@ -110,7 +110,7 @@ static int LUKS_check_device_size(struct crypt_device *ctx, const struct luks_ph
if (!hdr->keyBytes)
return -EINVAL;
if(device_size(device, &dev_sectors)) {
if (device_size(device, &dev_sectors)) {
log_dbg("Cannot get device size for device %s.", device_path(device));
return -EIO;
}
......@@ -121,6 +121,10 @@ static int LUKS_check_device_size(struct crypt_device *ctx, const struct luks_ph
PRIu64 " sectors.", hdr->keyBytes, dev_sectors, hdr_sectors);
if (hdr_sectors > dev_sectors) {
/* If it is header file, increase its size */
if (falloc && !device_fallocate(device, hdr_sectors << SECTOR_SHIFT))
return 0;
log_err(ctx, _("Device %s is too small. (LUKS requires at least %" PRIu64 " bytes.)\n"),
device_path(device), hdr_sectors * SECTOR_SIZE);
return -EINVAL;
......@@ -611,7 +615,7 @@ int LUKS_read_phdr(struct luks_phdr *hdr,
repair, ctx);
if (!r)
r = LUKS_check_device_size(ctx, hdr);
r = LUKS_check_device_size(ctx, hdr, 0);
/*
* Cryptsetup 1.0.0 did not align keyslots to 4k (very rare version).
......@@ -640,7 +644,7 @@ int LUKS_write_phdr(struct luks_phdr *hdr,
log_dbg("Updating LUKS header of size %zu on device %s",
sizeof(struct luks_phdr), device_path(device));
r = LUKS_check_device_size(ctx, hdr);
r = LUKS_check_device_size(ctx, hdr, 1);
if (r)
return r;
......
......@@ -343,7 +343,8 @@ static int hdr_write_disk(struct device *device, struct luks2_hdr *hdr,
return r;
}
static int LUKS2_check_device_size(struct crypt_device *cd, struct device *device, uint64_t hdr_size)
static int LUKS2_check_device_size(struct crypt_device *cd, struct device *device,
uint64_t hdr_size, int falloc)
{
uint64_t dev_size;
......@@ -356,6 +357,10 @@ static int LUKS2_check_device_size(struct crypt_device *cd, struct device *devic
PRIu64 ".", dev_size, hdr_size);
if (hdr_size > dev_size) {
/* If it is header file, increase its size */
if (falloc && !device_fallocate(device, hdr_size))
return 0;
log_err(cd, _("Device %s is too small. (LUKS2 requires at least %" PRIu64 " bytes.)\n"),
device_path(device), hdr_size);
return -EINVAL;
......@@ -385,7 +390,7 @@ int LUKS2_disk_hdr_write(struct crypt_device *cd, struct luks2_hdr *hdr, struct
return -EINVAL;
}
r = LUKS2_check_device_size(cd, crypt_metadata_device(cd), LUKS2_hdr_and_areas_size(hdr->jobj));
r = LUKS2_check_device_size(cd, crypt_metadata_device(cd), LUKS2_hdr_and_areas_size(hdr->jobj), 1);
if (r)
return r;
......@@ -589,7 +594,7 @@ int LUKS2_disk_hdr_read(struct crypt_device *cd, struct luks2_hdr *hdr,
goto err;
}
r = LUKS2_check_device_size(cd, device, hdr_size);
r = LUKS2_check_device_size(cd, device, hdr_size, 0);
if (r)
goto err;
......
......@@ -492,6 +492,24 @@ out:
return r;
}
/* For a file, allocate the required space */
int device_fallocate(struct device *device, uint64_t size)
{
struct stat st;
int devfd, r = -EINVAL;
devfd = open(device->path, O_WRONLY);
if(devfd == -1)
return -EINVAL;
if (!fstat(devfd, &st) && S_ISREG(st.st_mode) &&
!posix_fallocate(devfd, 0, size))
r = 0;
close(devfd);
return r;
}
static int device_info(struct crypt_device *cd,
struct device *device,
enum devcheck device_check,
......
......@@ -1016,7 +1016,7 @@ used with the \fIluksFormat\fR, \fIopen\fR, \fIluksSuspend\fR,
\fIluksResume\fR, \fIstatus\fR and \fIresize\fR commands.
For \fIluksFormat\fR with a file name as the argument to \-\-header,
it has to exist and be large enough to contain the LUKS header.
the file will be automatically created if it does not exist.
See the cryptsetup FAQ for header size calculation.
For other commands that change the LUKS header (e.g. \fIluksAddKey\fR),
......
......@@ -929,7 +929,8 @@ static int _wipe_data_device(struct crypt_device *cd)
static int action_luksFormat(void)
{
int r = -EINVAL, keysize, integrity_keysize = 0, luks_version;
int r = -EINVAL, keysize, integrity_keysize = 0, luks_version, fd;
struct stat st;
const char *header_device;
char *msg = NULL, *key = NULL, *password = NULL;
char cipher [MAX_CIPHER_LEN], cipher_mode[MAX_CIPHER_LEN], integrity[MAX_CIPHER_LEN];
......@@ -960,6 +961,24 @@ static int action_luksFormat(void)
return -EINVAL;
}
/* Create header file (must contain at least one sector)? */
if (opt_header_device && stat(opt_header_device, &st) < 0 && errno == ENOENT) {
if (!opt_batch_mode &&
!yesDialog("Header file does not exist, do you want to create it?", NULL))
return -EPERM;
log_dbg("Creating header file.");
fd = open(opt_header_device, O_CREAT|O_EXCL|O_WRONLY, S_IRUSR|S_IWUSR);
if (fd == -1 || posix_fallocate(fd, 0, 4096))
log_err(_("Cannot create header file %s.\n"), opt_header_device);
else
r = 0;
if (fd != -1)
close(fd);
if (r < 0)
return r;
}
header_device = opt_header_device ?: action_argv[0];
if(asprintf(&msg, _("This will overwrite data on %s irrevocably."),
......
......@@ -639,7 +639,6 @@ $CRYPTSETUP luksOpen -S 5 -d $KEY1 $LOOPDEV $DEV_NAME && fail
[ -b /dev/mapper/$DEV_NAME ] && fail
prepare "[28] Detached LUKS header" wipe
dd if=/dev/zero of=$HEADER_IMG bs=1M count=4 >/dev/null 2>&1
echo $PWD1 | $CRYPTSETUP luksFormat $FAST_PBKDF_OPT $LOOPDEV --header $HEADER_IMG || fail
echo $PWD1 | $CRYPTSETUP luksFormat $FAST_PBKDF_OPT $LOOPDEV --header $HEADER_IMG --align-payload 1 >/dev/null 2>&1 && fail
echo $PWD1 | $CRYPTSETUP luksFormat $FAST_PBKDF_OPT $LOOPDEV --header $HEADER_IMG --align-payload 8192 || fail
......
......@@ -569,7 +569,6 @@ echo $PWD1 | $CRYPTSETUP open --test-passphrase $HEADER_KEYU || fail
echo $PWD1 | $CRYPTSETUP open -S1 $HEADER_KEYU $DEV_NAME && fail
prepare "[28] Detached LUKS header" wipe
dd if=/dev/zero of=$HEADER_IMG bs=1M count=4 >/dev/null 2>&1
echo $PWD1 | $CRYPTSETUP luksFormat $FAST_PBKDF_OPT --type luks2 $LOOPDEV --header $HEADER_IMG || fail
#FIXME
#echo $PWD1 | $CRYPTSETUP luksFormat $FAST_PBKDF_OPT $LOOPDEV --header $HEADER_IMG --align-payload 1 >/dev/null 2>&1 && fail
......
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