Introduce new 64bit *keyfile_device_offset functions.

The keyfile interface was designed, well, for keyfiles.

Unfortunately, a keyfile can be placed on a device and the size_t offset
can overflow.

We have to introduce new set of fucntions that allows 64bit offsets even on 32bit systems:
 - crypt_resume_by_keyfile_device_offset
 - crypt_keyslot_add_by_keyfile_device_offset
 - crypt_activate_by_keyfile_device_offset
 - crypt_keyfile_device_read

The new functions have added _device_ in name.

Old functions are just internall wrappers around these.

Also cryptsetup --keyfile-offset and --new-keyfile-offset must now
process 64bit offsets.

For more info see issue 359.
This commit is contained in:
Milan Broz
2018-01-17 22:07:23 +01:00
parent b072c6c4c9
commit f34ce81f25
10 changed files with 202 additions and 75 deletions

View File

@@ -1,9 +1,9 @@
AC_PREREQ([2.67]) AC_PREREQ([2.67])
AC_INIT([cryptsetup],[2.0.0]) AC_INIT([cryptsetup],[2.0.1-git])
dnl library version from <major>.<minor>.<release>[-<suffix>] dnl library version from <major>.<minor>.<release>[-<suffix>]
LIBCRYPTSETUP_VERSION=$(echo $PACKAGE_VERSION | cut -f1 -d-) LIBCRYPTSETUP_VERSION=$(echo $PACKAGE_VERSION | cut -f1 -d-)
LIBCRYPTSETUP_VERSION_INFO=12:0:0 LIBCRYPTSETUP_VERSION_INFO=13:0:1
AM_SILENT_RULES([yes]) AM_SILENT_RULES([yes])
AC_CONFIG_SRCDIR(src/cryptsetup.c) AC_CONFIG_SRCDIR(src/cryptsetup.c)

View File

@@ -696,14 +696,25 @@ int crypt_resume_by_passphrase(struct crypt_device *cd,
* *
* @return unlocked key slot number or negative errno otherwise. * @return unlocked key slot number or negative errno otherwise.
*/ */
int crypt_resume_by_keyfile_device_offset(struct crypt_device *cd,
const char *name,
int keyslot,
const char *keyfile,
size_t keyfile_size,
uint64_t keyfile_offset);
/**
* Backward compatible crypt_resume_by_keyfile_device_offset() (with size_t offset).
*/
int crypt_resume_by_keyfile_offset(struct crypt_device *cd, int crypt_resume_by_keyfile_offset(struct crypt_device *cd,
const char *name, const char *name,
int keyslot, int keyslot,
const char *keyfile, const char *keyfile,
size_t keyfile_size, size_t keyfile_size,
size_t keyfile_offset); size_t keyfile_offset);
/** /**
* Backward compatible crypt_resume_by_keyfile_offset() (without offset). * Backward compatible crypt_resume_by_keyfile_device_offset() (without offset).
*/ */
int crypt_resume_by_keyfile(struct crypt_device *cd, int crypt_resume_by_keyfile(struct crypt_device *cd,
const char *name, const char *name,
@@ -785,6 +796,18 @@ int crypt_keyslot_change_by_passphrase(struct crypt_device *cd,
* *
* @return allocated key slot number or negative errno otherwise. * @return allocated key slot number or negative errno otherwise.
*/ */
int crypt_keyslot_add_by_keyfile_device_offset(struct crypt_device *cd,
int keyslot,
const char *keyfile,
size_t keyfile_size,
uint64_t keyfile_offset,
const char *new_keyfile,
size_t new_keyfile_size,
uint64_t new_keyfile_offset);
/**
* Backward compatible crypt_keyslot_add_by_keyfile_device_offset() (with size_t offset).
*/
int crypt_keyslot_add_by_keyfile_offset(struct crypt_device *cd, int crypt_keyslot_add_by_keyfile_offset(struct crypt_device *cd,
int keyslot, int keyslot,
const char *keyfile, const char *keyfile,
@@ -793,8 +816,9 @@ int crypt_keyslot_add_by_keyfile_offset(struct crypt_device *cd,
const char *new_keyfile, const char *new_keyfile,
size_t new_keyfile_size, size_t new_keyfile_size,
size_t new_keyfile_offset); size_t new_keyfile_offset);
/** /**
* Backward compatible crypt_keyslot_add_by_keyfile_offset() (without offset). * Backward compatible crypt_keyslot_add_by_keyfile_device_offset() (without offset).
*/ */
int crypt_keyslot_add_by_keyfile(struct crypt_device *cd, int crypt_keyslot_add_by_keyfile(struct crypt_device *cd,
int keyslot, int keyslot,
@@ -1030,6 +1054,17 @@ int crypt_activate_by_passphrase(struct crypt_device *cd,
* *
* @return unlocked key slot number or negative errno otherwise. * @return unlocked key slot number or negative errno otherwise.
*/ */
int crypt_activate_by_keyfile_device_offset(struct crypt_device *cd,
const char *name,
int keyslot,
const char *keyfile,
size_t keyfile_size,
uint64_t keyfile_offset,
uint32_t flags);
/**
* Backward compatible crypt_activate_by_keyfile_device_offset() (with size_t offset).
*/
int crypt_activate_by_keyfile_offset(struct crypt_device *cd, int crypt_activate_by_keyfile_offset(struct crypt_device *cd,
const char *name, const char *name,
int keyslot, int keyslot,
@@ -1037,8 +1072,9 @@ int crypt_activate_by_keyfile_offset(struct crypt_device *cd,
size_t keyfile_size, size_t keyfile_size,
size_t keyfile_offset, size_t keyfile_offset,
uint32_t flags); uint32_t flags);
/** /**
* Backward compatible crypt_activate_by_keyfile_offset() (without offset). * Backward compatible crypt_activate_by_keyfile_device_offset() (without offset).
*/ */
int crypt_activate_by_keyfile(struct crypt_device *cd, int crypt_activate_by_keyfile(struct crypt_device *cd,
const char *name, const char *name,
@@ -1050,7 +1086,6 @@ int crypt_activate_by_keyfile(struct crypt_device *cd,
/** /**
* Activate device using provided volume key. * Activate device using provided volume key.
* *
*
* @param cd crypt device handle * @param cd crypt device handle
* @param name name of device to create, if @e NULL only check volume key * @param name name of device to create, if @e NULL only check volume key
* @param volume_key provided volume key (or @e NULL to use internal) * @param volume_key provided volume key (or @e NULL to use internal)
@@ -1077,7 +1112,6 @@ int crypt_activate_by_volume_key(struct crypt_device *cd,
/** /**
* Activate device using passphrase stored in kernel keyring. * Activate device using passphrase stored in kernel keyring.
* *
*
* @param cd crypt device handle * @param cd crypt device handle
* @param name name of device to create, if @e NULL only check passphrase in keyring * @param name name of device to create, if @e NULL only check passphrase in keyring
* @param key_description kernel keyring key description library should look * @param key_description kernel keyring key description library should look
@@ -1386,7 +1420,6 @@ typedef enum {
/** /**
* Get information about particular key slot. * Get information about particular key slot.
* *
*
* @param cd crypt device handle * @param cd crypt device handle
* @param keyslot requested keyslot to check or CRYPT_ANY_SLOT * @param keyslot requested keyslot to check or CRYPT_ANY_SLOT
* *
@@ -1483,7 +1516,6 @@ int crypt_header_backup(struct crypt_device *cd,
/** /**
* Restore header and keyslots from backup file. * Restore header and keyslots from backup file.
* *
*
* @param cd crypt device handle * @param cd crypt device handle
* @param requested_type @link crypt-type @endlink or @e NULL for all known * @param requested_type @link crypt-type @endlink or @e NULL for all known
* @param backup_file file to restore header from * @param backup_file file to restore header from
@@ -1526,15 +1558,34 @@ void crypt_set_debug_level(int level);
/** /**
* Read keyfile * Read keyfile
* *
* @param cd crypt device handle
* @param keyfile keyfile to read
* @param key buffer for key
* @param key_size_read size of read key
* @param keyfile_offset keyfile offset
* @param keyfile_size_max maximal size of keyfile to read
* @param flags keyfile read flags
*
* @return @e 0 on success or negative errno value otherwise.
*/
int crypt_keyfile_device_read(struct crypt_device *cd,
const char *keyfile,
char **key, size_t *key_size_read,
uint64_t keyfile_offset,
size_t keyfile_size_max,
uint32_t flags);
/**
* Backward compatible crypt_keyfile_device_read() (with size_t offset).
*/ */
int crypt_keyfile_read(struct crypt_device *cd, int crypt_keyfile_read(struct crypt_device *cd,
const char *keyfile, const char *keyfile,
char **key, size_t *key_size_read, char **key, size_t *key_size_read,
size_t keyfile_offset, size_t keyfile_offset,
size_t keyfile_size_max, size_t keyfile_size_max,
uint32_t flags uint32_t flags);
);
/** No on-disk header (only hashes) */ /** Read key only to the first end of line (\\n). */
#define CRYPT_KEYFILE_STOP_EOL (1 << 0) #define CRYPT_KEYFILE_STOP_EOL (1 << 0)
/** @} */ /** @} */
@@ -1600,7 +1651,7 @@ int crypt_wipe(struct crypt_device *cd,
* @{ * @{
*/ */
/** iterate through all tokens */ /** Iterate through all tokens */
#define CRYPT_ANY_TOKEN -1 #define CRYPT_ANY_TOKEN -1
/** /**

View File

@@ -22,12 +22,14 @@ CRYPTSETUP_2.0 {
crypt_resume_by_passphrase; crypt_resume_by_passphrase;
crypt_resume_by_keyfile; crypt_resume_by_keyfile;
crypt_resume_by_keyfile_offset; crypt_resume_by_keyfile_offset;
crypt_resume_by_keyfile_device_offset;
crypt_free; crypt_free;
crypt_keyslot_add_by_passphrase; crypt_keyslot_add_by_passphrase;
crypt_keyslot_change_by_passphrase; crypt_keyslot_change_by_passphrase;
crypt_keyslot_add_by_keyfile; crypt_keyslot_add_by_keyfile;
crypt_keyslot_add_by_keyfile_offset; crypt_keyslot_add_by_keyfile_offset;
crypt_keyslot_add_by_keyfile_device_offset;
crypt_keyslot_add_by_volume_key; crypt_keyslot_add_by_volume_key;
crypt_keyslot_add_by_key; crypt_keyslot_add_by_key;
@@ -49,6 +51,7 @@ CRYPTSETUP_2.0 {
crypt_activate_by_passphrase; crypt_activate_by_passphrase;
crypt_activate_by_keyfile; crypt_activate_by_keyfile;
crypt_activate_by_keyfile_offset; crypt_activate_by_keyfile_offset;
crypt_activate_by_keyfile_device_offset;
crypt_activate_by_volume_key; crypt_activate_by_volume_key;
crypt_activate_by_keyring; crypt_activate_by_keyring;
crypt_deactivate; crypt_deactivate;
@@ -92,6 +95,7 @@ CRYPTSETUP_2.0 {
crypt_header_restore; crypt_header_restore;
crypt_keyfile_read; crypt_keyfile_read;
crypt_keyfile_device_read;
crypt_wipe; crypt_wipe;
local: local:

View File

@@ -2467,12 +2467,12 @@ out:
return r < 0 ? r : keyslot; return r < 0 ? r : keyslot;
} }
int crypt_resume_by_keyfile_offset(struct crypt_device *cd, int crypt_resume_by_keyfile_device_offset(struct crypt_device *cd,
const char *name, const char *name,
int keyslot, int keyslot,
const char *keyfile, const char *keyfile,
size_t keyfile_size, size_t keyfile_size,
size_t keyfile_offset) uint64_t keyfile_offset)
{ {
struct volume_key *vk = NULL; struct volume_key *vk = NULL;
char *passphrase_read = NULL; char *passphrase_read = NULL;
@@ -2498,9 +2498,9 @@ int crypt_resume_by_keyfile_offset(struct crypt_device *cd,
return -EINVAL; return -EINVAL;
} }
r = crypt_keyfile_read(cd, keyfile, r = crypt_keyfile_device_read(cd, keyfile,
&passphrase_read, &passphrase_size_read, &passphrase_read, &passphrase_size_read,
keyfile_offset, keyfile_size, 0); keyfile_offset, keyfile_size, 0);
if (r < 0) if (r < 0)
goto out; goto out;
@@ -2537,10 +2537,21 @@ int crypt_resume_by_keyfile(struct crypt_device *cd,
const char *keyfile, const char *keyfile,
size_t keyfile_size) size_t keyfile_size)
{ {
return crypt_resume_by_keyfile_offset(cd, name, keyslot, return crypt_resume_by_keyfile_device_offset(cd, name, keyslot,
keyfile, keyfile_size, 0); keyfile, keyfile_size, 0);
} }
int crypt_resume_by_keyfile_offset(struct crypt_device *cd,
const char *name,
int keyslot,
const char *keyfile,
size_t keyfile_size,
size_t keyfile_offset)
{
return crypt_resume_by_keyfile_device_offset(cd, name, keyslot,
keyfile, keyfile_size, keyfile_offset);
}
/* /*
* Keyslot manipulation * Keyslot manipulation
*/ */
@@ -2726,14 +2737,14 @@ out:
return keyslot_new; return keyslot_new;
} }
int crypt_keyslot_add_by_keyfile_offset(struct crypt_device *cd, int crypt_keyslot_add_by_keyfile_device_offset(struct crypt_device *cd,
int keyslot, int keyslot,
const char *keyfile, const char *keyfile,
size_t keyfile_size, size_t keyfile_size,
size_t keyfile_offset, uint64_t keyfile_offset,
const char *new_keyfile, const char *new_keyfile,
size_t new_keyfile_size, size_t new_keyfile_size,
size_t new_keyfile_offset) uint64_t new_keyfile_offset)
{ {
int digest, r, active_slots; int digest, r, active_slots;
size_t passwordLen, new_passwordLen; size_t passwordLen, new_passwordLen;
@@ -2767,7 +2778,7 @@ int crypt_keyslot_add_by_keyfile_offset(struct crypt_device *cd,
return -EINVAL; return -EINVAL;
} }
} else { } else {
r = crypt_keyfile_read(cd, keyfile, r = crypt_keyfile_device_read(cd, keyfile,
&password, &passwordLen, &password, &passwordLen,
keyfile_offset, keyfile_size, 0); keyfile_offset, keyfile_size, 0);
if (r < 0) if (r < 0)
@@ -2783,7 +2794,7 @@ int crypt_keyslot_add_by_keyfile_offset(struct crypt_device *cd,
if (r < 0) if (r < 0)
goto out; goto out;
r = crypt_keyfile_read(cd, new_keyfile, r = crypt_keyfile_device_read(cd, new_keyfile,
&new_password, &new_passwordLen, &new_password, &new_passwordLen,
new_keyfile_offset, new_keyfile_size, 0); new_keyfile_offset, new_keyfile_size, 0);
if (r < 0) if (r < 0)
@@ -2821,11 +2832,25 @@ int crypt_keyslot_add_by_keyfile(struct crypt_device *cd,
const char *new_keyfile, const char *new_keyfile,
size_t new_keyfile_size) size_t new_keyfile_size)
{ {
return crypt_keyslot_add_by_keyfile_offset(cd, keyslot, return crypt_keyslot_add_by_keyfile_device_offset(cd, keyslot,
keyfile, keyfile_size, 0, keyfile, keyfile_size, 0,
new_keyfile, new_keyfile_size, 0); new_keyfile, new_keyfile_size, 0);
} }
int crypt_keyslot_add_by_keyfile_offset(struct crypt_device *cd,
int keyslot,
const char *keyfile,
size_t keyfile_size,
size_t keyfile_offset,
const char *new_keyfile,
size_t new_keyfile_size,
size_t new_keyfile_offset)
{
return crypt_keyslot_add_by_keyfile_device_offset(cd, keyslot,
keyfile, keyfile_size, keyfile_offset,
new_keyfile, new_keyfile_size, new_keyfile_offset);
}
int crypt_keyslot_add_by_volume_key(struct crypt_device *cd, int crypt_keyslot_add_by_volume_key(struct crypt_device *cd,
int keyslot, int keyslot,
const char *volume_key, const char *volume_key,
@@ -3033,12 +3058,12 @@ int crypt_activate_by_passphrase(struct crypt_device *cd,
return _activate_by_passphrase(cd, name, keyslot, passphrase, passphrase_size, flags); return _activate_by_passphrase(cd, name, keyslot, passphrase, passphrase_size, flags);
} }
int crypt_activate_by_keyfile_offset(struct crypt_device *cd, int crypt_activate_by_keyfile_device_offset(struct crypt_device *cd,
const char *name, const char *name,
int keyslot, int keyslot,
const char *keyfile, const char *keyfile,
size_t keyfile_size, size_t keyfile_size,
size_t keyfile_offset, uint64_t keyfile_offset,
uint32_t flags) uint32_t flags)
{ {
struct volume_key *vk = NULL; struct volume_key *vk = NULL;
@@ -3061,9 +3086,9 @@ int crypt_activate_by_keyfile_offset(struct crypt_device *cd,
if (!name) if (!name)
return -EINVAL; return -EINVAL;
r = crypt_keyfile_read(cd, keyfile, r = crypt_keyfile_device_read(cd, keyfile,
&passphrase_read, &passphrase_size_read, &passphrase_read, &passphrase_size_read,
keyfile_offset, keyfile_size, 0); keyfile_offset, keyfile_size, 0);
if (r < 0) if (r < 0)
goto out; goto out;
@@ -3075,9 +3100,9 @@ int crypt_activate_by_keyfile_offset(struct crypt_device *cd,
r = PLAIN_activate(cd, name, vk, cd->u.plain.hdr.size, flags); r = PLAIN_activate(cd, name, vk, cd->u.plain.hdr.size, flags);
} else if (isLUKS1(cd->type)) { } else if (isLUKS1(cd->type)) {
r = crypt_keyfile_read(cd, keyfile, r = crypt_keyfile_device_read(cd, keyfile,
&passphrase_read, &passphrase_size_read, &passphrase_read, &passphrase_size_read,
keyfile_offset, keyfile_size, 0); keyfile_offset, keyfile_size, 0);
if (r < 0) if (r < 0)
goto out; goto out;
r = LUKS_open_key_with_hdr(keyslot, passphrase_read, r = LUKS_open_key_with_hdr(keyslot, passphrase_read,
@@ -3093,9 +3118,9 @@ int crypt_activate_by_keyfile_offset(struct crypt_device *cd,
} }
r = keyslot; r = keyslot;
} else if (isLUKS2(cd->type)) { } else if (isLUKS2(cd->type)) {
r = crypt_keyfile_read(cd, keyfile, r = crypt_keyfile_device_read(cd, keyfile,
&passphrase_read, &passphrase_size_read, &passphrase_read, &passphrase_size_read,
keyfile_offset, keyfile_size, 0); keyfile_offset, keyfile_size, 0);
if (r < 0) if (r < 0)
goto out; goto out;
@@ -3120,9 +3145,9 @@ int crypt_activate_by_keyfile_offset(struct crypt_device *cd,
} }
r = keyslot; r = keyslot;
} else if (isLOOPAES(cd->type)) { } else if (isLOOPAES(cd->type)) {
r = crypt_keyfile_read(cd, keyfile, r = crypt_keyfile_device_read(cd, keyfile,
&passphrase_read, &passphrase_size_read, &passphrase_read, &passphrase_size_read,
keyfile_offset, keyfile_size, 0); keyfile_offset, keyfile_size, 0);
if (r < 0) if (r < 0)
goto out; goto out;
r = LOOPAES_parse_keyfile(cd, &vk, cd->u.loopaes.hdr.hash, &key_count, r = LOOPAES_parse_keyfile(cd, &vk, cd->u.loopaes.hdr.hash, &key_count,
@@ -3152,8 +3177,20 @@ int crypt_activate_by_keyfile(struct crypt_device *cd,
size_t keyfile_size, size_t keyfile_size,
uint32_t flags) uint32_t flags)
{ {
return crypt_activate_by_keyfile_offset(cd, name, keyslot, keyfile, return crypt_activate_by_keyfile_device_offset(cd, name, keyslot, keyfile,
keyfile_size, 0, flags); keyfile_size, 0, flags);
}
int crypt_activate_by_keyfile_offset(struct crypt_device *cd,
const char *name,
int keyslot,
const char *keyfile,
size_t keyfile_size,
size_t keyfile_offset,
uint32_t flags)
{
return crypt_activate_by_keyfile_device_offset(cd, name, keyslot, keyfile,
keyfile_size, keyfile_offset, flags);
} }
int crypt_activate_by_volume_key(struct crypt_device *cd, int crypt_activate_by_volume_key(struct crypt_device *cd,

View File

@@ -359,28 +359,32 @@ int crypt_memlock_dec(struct crypt_device *ctx)
* or when it reaches EOF before the requested number of bytes have been * or when it reaches EOF before the requested number of bytes have been
* discarded. * discarded.
*/ */
static int keyfile_seek(int fd, size_t bytes) static int keyfile_seek(int fd, uint64_t bytes)
{ {
char tmp[BUFSIZ]; char tmp[BUFSIZ];
size_t next_read; size_t next_read;
ssize_t bytes_r; ssize_t bytes_r;
off_t r; off64_t r;
r = lseek(fd, bytes, SEEK_CUR); r = lseek64(fd, bytes, SEEK_CUR);
if (r > 0) if (r > 0)
return 0; return 0;
if (r < 0 && errno != ESPIPE) if (r < 0 && errno != ESPIPE)
return -1; return -1;
if (bytes > SIZE_MAX)
return -1;
while (bytes > 0) { while (bytes > 0) {
/* figure out how much to read */ /* figure out how much to read */
next_read = bytes > sizeof(tmp) ? sizeof(tmp) : bytes; next_read = bytes > sizeof(tmp) ? sizeof(tmp) : (size_t)bytes;
bytes_r = read(fd, tmp, next_read); bytes_r = read(fd, tmp, next_read);
if (bytes_r < 0) { if (bytes_r < 0) {
if (errno == EINTR) if (errno == EINTR)
continue; continue;
crypt_memzero(tmp, sizeof(tmp));
/* read error */ /* read error */
return -1; return -1;
} }
@@ -392,18 +396,20 @@ static int keyfile_seek(int fd, size_t bytes)
bytes -= bytes_r; bytes -= bytes_r;
} }
crypt_memzero(tmp, sizeof(tmp));
return bytes == 0 ? 0 : -1; return bytes == 0 ? 0 : -1;
} }
int crypt_keyfile_read(struct crypt_device *cd, const char *keyfile, int crypt_keyfile_device_read(struct crypt_device *cd, const char *keyfile,
char **key, size_t *key_size_read, char **key, size_t *key_size_read,
size_t keyfile_offset, size_t keyfile_size_max, uint64_t keyfile_offset, size_t keyfile_size_max,
uint32_t flags) uint32_t flags)
{ {
int fd, regular_file, char_to_read = 0, char_read = 0, unlimited_read = 0; int fd, regular_file, char_to_read = 0, char_read = 0, unlimited_read = 0;
int r = -EINVAL, newline; int r = -EINVAL, newline;
char *pass = NULL; char *pass = NULL;
size_t buflen, i, file_read_size; size_t buflen, i;
uint64_t file_read_size;
struct stat st; struct stat st;
if (!key || !key_size_read) if (!key || !key_size_read)
@@ -441,7 +447,7 @@ int crypt_keyfile_read(struct crypt_device *cd, const char *keyfile,
} }
if (S_ISREG(st.st_mode)) { if (S_ISREG(st.st_mode)) {
regular_file = 1; regular_file = 1;
file_read_size = (size_t)st.st_size; file_read_size = (uint64_t)st.st_size;
if (keyfile_offset > file_read_size) { if (keyfile_offset > file_read_size) {
log_err(cd, _("Cannot seek to requested keyfile offset.\n")); log_err(cd, _("Cannot seek to requested keyfile offset.\n"));
@@ -450,7 +456,7 @@ int crypt_keyfile_read(struct crypt_device *cd, const char *keyfile,
file_read_size -= keyfile_offset; file_read_size -= keyfile_offset;
/* known keyfile size, alloc it in one step */ /* known keyfile size, alloc it in one step */
if (file_read_size >= keyfile_size_max) if (file_read_size >= (uint64_t)keyfile_size_max)
buflen = keyfile_size_max; buflen = keyfile_size_max;
else if (file_read_size) else if (file_read_size)
buflen = file_read_size; buflen = file_read_size;
@@ -538,3 +544,12 @@ out_err:
crypt_safe_free(pass); crypt_safe_free(pass);
return r; return r;
} }
int crypt_keyfile_read(struct crypt_device *cd, const char *keyfile,
char **key, size_t *key_size_read,
size_t keyfile_offset, size_t keyfile_size_max,
uint32_t flags)
{
return crypt_keyfile_device_read(cd, keyfile, key, key_size_read,
keyfile_offset, keyfile_size_max, flags);
}

View File

@@ -41,8 +41,8 @@ static const char *opt_type = "luks";
static int opt_key_size = 0; static int opt_key_size = 0;
static long opt_keyfile_size = 0; static long opt_keyfile_size = 0;
static long opt_new_keyfile_size = 0; static long opt_new_keyfile_size = 0;
static long opt_keyfile_offset = 0; static uint64_t opt_keyfile_offset = 0;
static long opt_new_keyfile_offset = 0; static uint64_t opt_new_keyfile_offset = 0;
static int opt_key_slot = CRYPT_ANY_SLOT; static int opt_key_slot = CRYPT_ANY_SLOT;
static int opt_token = CRYPT_ANY_TOKEN; static int opt_token = CRYPT_ANY_TOKEN;
static int opt_token_only = 0; static int opt_token_only = 0;
@@ -220,7 +220,7 @@ static int action_open_plain(void)
* The opt_keyfile_offset is applied always. * The opt_keyfile_offset is applied always.
*/ */
key_size_max = params.hash ? (size_t)opt_keyfile_size : key_size; key_size_max = params.hash ? (size_t)opt_keyfile_size : key_size;
r = crypt_activate_by_keyfile_offset(cd, action_argv[1], r = crypt_activate_by_keyfile_device_offset(cd, action_argv[1],
CRYPT_ANY_SLOT, opt_key_file, key_size_max, CRYPT_ANY_SLOT, opt_key_file, key_size_max,
opt_keyfile_offset, activate_flags); opt_keyfile_offset, activate_flags);
} else { } else {
@@ -270,7 +270,7 @@ static int action_open_loopaes(void)
if (r < 0) if (r < 0)
goto out; goto out;
r = crypt_activate_by_keyfile_offset(cd, action_argv[1], CRYPT_ANY_SLOT, r = crypt_activate_by_keyfile_device_offset(cd, action_argv[1], CRYPT_ANY_SLOT,
opt_key_file, opt_keyfile_size, opt_key_file, opt_keyfile_size,
opt_keyfile_offset, activate_flags); opt_keyfile_offset, activate_flags);
out: out:
@@ -1150,7 +1150,7 @@ out:
static int verify_keyslot(struct crypt_device *cd, int key_slot, static int verify_keyslot(struct crypt_device *cd, int key_slot,
char *msg_last, char *msg_pass, char *msg_last, char *msg_pass,
const char *key_file, int keyfile_offset, const char *key_file, uint64_t keyfile_offset,
int keyfile_size) int keyfile_size)
{ {
crypt_keyslot_info ki; crypt_keyslot_info ki;
@@ -1335,7 +1335,7 @@ static int action_luksAddKey(void)
password_new, password_new_size); password_new, password_new_size);
} else if (opt_key_file && !tools_is_stdin(opt_key_file) && } else if (opt_key_file && !tools_is_stdin(opt_key_file) &&
opt_new_key_file && !tools_is_stdin(opt_new_key_file)) { opt_new_key_file && !tools_is_stdin(opt_new_key_file)) {
r = crypt_keyslot_add_by_keyfile_offset(cd, opt_key_slot, r = crypt_keyslot_add_by_keyfile_device_offset(cd, opt_key_slot,
opt_key_file, opt_keyfile_size, opt_keyfile_offset, opt_key_file, opt_keyfile_size, opt_keyfile_offset,
opt_new_key_file, opt_new_keyfile_size, opt_new_keyfile_offset); opt_new_key_file, opt_new_keyfile_size, opt_new_keyfile_offset);
} else { } else {
@@ -2027,14 +2027,14 @@ int main(int argc, const char **argv)
{ "cipher", 'c', POPT_ARG_STRING, &opt_cipher, 0, N_("The cipher used to encrypt the disk (see /proc/crypto)"), NULL }, { "cipher", 'c', POPT_ARG_STRING, &opt_cipher, 0, N_("The cipher used to encrypt the disk (see /proc/crypto)"), NULL },
{ "hash", 'h', POPT_ARG_STRING, &opt_hash, 0, N_("The hash used to create the encryption key from the passphrase"), NULL }, { "hash", 'h', POPT_ARG_STRING, &opt_hash, 0, N_("The hash used to create the encryption key from the passphrase"), NULL },
{ "verify-passphrase", 'y', POPT_ARG_NONE, &opt_verify_passphrase, 0, N_("Verifies the passphrase by asking for it twice"), NULL }, { "verify-passphrase", 'y', POPT_ARG_NONE, &opt_verify_passphrase, 0, N_("Verifies the passphrase by asking for it twice"), NULL },
{ "key-file", 'd', POPT_ARG_STRING, &opt_key_file, 5, N_("Read the key from a file."), NULL }, { "key-file", 'd', POPT_ARG_STRING, &opt_key_file, 6, N_("Read the key from a file."), NULL },
{ "master-key-file", '\0', POPT_ARG_STRING, &opt_master_key_file, 0, N_("Read the volume (master) key from file."), NULL }, { "master-key-file", '\0', POPT_ARG_STRING, &opt_master_key_file, 0, N_("Read the volume (master) key from file."), NULL },
{ "dump-master-key", '\0', POPT_ARG_NONE, &opt_dump_master_key, 0, N_("Dump volume (master) key instead of keyslots info."), NULL }, { "dump-master-key", '\0', POPT_ARG_NONE, &opt_dump_master_key, 0, N_("Dump volume (master) key instead of keyslots info."), NULL },
{ "key-size", 's', POPT_ARG_INT, &opt_key_size, 0, N_("The size of the encryption key"), N_("BITS") }, { "key-size", 's', POPT_ARG_INT, &opt_key_size, 0, N_("The size of the encryption key"), N_("BITS") },
{ "keyfile-size", 'l', POPT_ARG_LONG, &opt_keyfile_size, 0, N_("Limits the read from keyfile"), N_("bytes") }, { "keyfile-size", 'l', POPT_ARG_LONG, &opt_keyfile_size, 0, N_("Limits the read from keyfile"), N_("bytes") },
{ "keyfile-offset", '\0', POPT_ARG_LONG, &opt_keyfile_offset, 0, N_("Number of bytes to skip in keyfile"), N_("bytes") }, { "keyfile-offset", '\0', POPT_ARG_STRING, &popt_tmp, 4, N_("Number of bytes to skip in keyfile"), N_("bytes") },
{ "new-keyfile-size", '\0', POPT_ARG_LONG, &opt_new_keyfile_size, 0, N_("Limits the read from newly added keyfile"), N_("bytes") }, { "new-keyfile-size", '\0', POPT_ARG_LONG, &opt_new_keyfile_size, 0, N_("Limits the read from newly added keyfile"), N_("bytes") },
{ "new-keyfile-offset",'\0', POPT_ARG_LONG, &opt_new_keyfile_offset, 0, N_("Number of bytes to skip in newly added keyfile"), N_("bytes") }, { "new-keyfile-offset",'\0', POPT_ARG_STRING, &popt_tmp, 5, N_("Number of bytes to skip in newly added keyfile"), N_("bytes") },
{ "key-slot", 'S', POPT_ARG_INT, &opt_key_slot, 0, N_("Slot number for new key (default is first free)"), NULL }, { "key-slot", 'S', POPT_ARG_INT, &opt_key_slot, 0, N_("Slot number for new key (default is first free)"), NULL },
{ "size", 'b', POPT_ARG_STRING, &popt_tmp, 1, N_("The size of the device"), N_("SECTORS") }, { "size", 'b', POPT_ARG_STRING, &popt_tmp, 1, N_("The size of the device"), N_("SECTORS") },
{ "offset", 'o', POPT_ARG_STRING, &popt_tmp, 2, N_("The start offset in the backend device"), N_("SECTORS") }, { "offset", 'o', POPT_ARG_STRING, &popt_tmp, 2, N_("The start offset in the backend device"), N_("SECTORS") },
@@ -2103,7 +2103,7 @@ int main(int argc, const char **argv)
unsigned long long ull_value; unsigned long long ull_value;
char *endp, *kf; char *endp, *kf;
if (r == 5) { if (r == 6) {
kf = poptGetOptArg(popt_context); kf = poptGetOptArg(popt_context);
if (tools_is_stdin(kf)) if (tools_is_stdin(kf))
opt_keyfile_stdin = kf; opt_keyfile_stdin = kf;
@@ -2115,7 +2115,7 @@ int main(int argc, const char **argv)
errno = 0; errno = 0;
ull_value = strtoull(popt_tmp, &endp, 0); ull_value = strtoull(popt_tmp, &endp, 0);
if (*endp || !*popt_tmp || if (*endp || !*popt_tmp || !isdigit(*popt_tmp) ||
(errno == ERANGE && ull_value == ULLONG_MAX) || (errno == ERANGE && ull_value == ULLONG_MAX) ||
(errno != 0 && ull_value == 0)) (errno != 0 && ull_value == 0))
r = POPT_ERROR_BADNUMBER; r = POPT_ERROR_BADNUMBER;
@@ -2131,6 +2131,12 @@ int main(int argc, const char **argv)
opt_skip = ull_value; opt_skip = ull_value;
opt_skip_valid = 1; opt_skip_valid = 1;
break; break;
case 4:
opt_keyfile_offset = ull_value;
break;
case 5:
opt_new_keyfile_offset = ull_value;
break;
} }
if (r < 0) if (r < 0)
@@ -2283,8 +2289,7 @@ int main(int argc, const char **argv)
opt_key_file = action_argv[1]; opt_key_file = action_argv[1];
} }
if (opt_keyfile_size < 0 || opt_new_keyfile_size < 0 || opt_key_size < 0 || if (opt_keyfile_size < 0 || opt_new_keyfile_size < 0 || opt_key_size < 0)
opt_keyfile_offset < 0 || opt_new_keyfile_offset < 0)
usage(popt_context, EXIT_FAILURE, usage(popt_context, EXIT_FAILURE,
_("Negative number for option not permitted."), _("Negative number for option not permitted."),
poptGetInvocationName(popt_context)); poptGetInvocationName(popt_context));

View File

@@ -83,7 +83,7 @@ int tools_signals_blocked(void);
int tools_get_key(const char *prompt, int tools_get_key(const char *prompt,
char **key, size_t *key_size, char **key, size_t *key_size,
size_t keyfile_offset, size_t keyfile_size_max, uint64_t keyfile_offset, size_t keyfile_size_max,
const char *key_file, const char *key_file,
int timeout, int verify, int pwquality, int timeout, int verify, int pwquality,
struct crypt_device *cd); struct crypt_device *cd);

View File

@@ -251,7 +251,7 @@ out_err:
*/ */
int tools_get_key(const char *prompt, int tools_get_key(const char *prompt,
char **key, size_t *key_size, char **key, size_t *key_size,
size_t keyfile_offset, size_t keyfile_size_max, uint64_t keyfile_offset, size_t keyfile_size_max,
const char *key_file, const char *key_file,
int timeout, int verify, int pwquality, int timeout, int verify, int pwquality,
struct crypt_device *cd) struct crypt_device *cd)
@@ -278,12 +278,14 @@ int tools_get_key(const char *prompt,
} else { } else {
log_dbg("STDIN descriptor passphrase entry requested."); log_dbg("STDIN descriptor passphrase entry requested.");
/* No keyfile means STDIN with EOL handling (\n will end input)). */ /* No keyfile means STDIN with EOL handling (\n will end input)). */
r = crypt_keyfile_read(cd, NULL, key, key_size, keyfile_offset, keyfile_size_max, r = crypt_keyfile_device_read(cd, NULL, key, key_size,
key_file ? 0 : CRYPT_KEYFILE_STOP_EOL); keyfile_offset, keyfile_size_max,
key_file ? 0 : CRYPT_KEYFILE_STOP_EOL);
} }
} else { } else {
log_dbg("File descriptor passphrase entry requested."); log_dbg("File descriptor passphrase entry requested.");
r = crypt_keyfile_read(cd, key_file, key, key_size, keyfile_offset, keyfile_size_max, 0); r = crypt_keyfile_device_read(cd, key_file, key, key_size,
keyfile_offset, keyfile_size_max, 0);
} }
if (block && !quit) if (block && !quit)

View File

@@ -567,8 +567,11 @@ static void AddDevicePlain(void)
EQ_(crypt_status(cd, CDEVICE_1), CRYPT_ACTIVE); EQ_(crypt_status(cd, CDEVICE_1), CRYPT_ACTIVE);
OK_(crypt_deactivate(cd, CDEVICE_1)); OK_(crypt_deactivate(cd, CDEVICE_1));
FAIL_(crypt_activate_by_keyfile_offset(cd, NULL, CRYPT_ANY_SLOT, KEYFILE1, 0, strlen(KEY1) + 1, 0), "cannot seek"); FAIL_(crypt_activate_by_keyfile_offset(cd, NULL, CRYPT_ANY_SLOT, KEYFILE1, 0, strlen(KEY1) + 1, 0), "cannot seek");
FAIL_(crypt_activate_by_keyfile_device_offset(cd, NULL, CRYPT_ANY_SLOT, KEYFILE1, 0, strlen(KEY1) + 1, 0), "cannot seek");
EQ_(0, crypt_activate_by_keyfile_offset(cd, CDEVICE_1, CRYPT_ANY_SLOT, KEYFILE1, 0, 0, 0)); EQ_(0, crypt_activate_by_keyfile_offset(cd, CDEVICE_1, CRYPT_ANY_SLOT, KEYFILE1, 0, 0, 0));
OK_(crypt_deactivate(cd, CDEVICE_1)); OK_(crypt_deactivate(cd, CDEVICE_1));
EQ_(0, crypt_activate_by_keyfile_device_offset(cd, CDEVICE_1, CRYPT_ANY_SLOT, KEYFILE1, 0, 0, 0));
OK_(crypt_deactivate(cd, CDEVICE_1));
_remove_keyfiles(); _remove_keyfiles();
crypt_free(cd); crypt_free(cd);
@@ -689,7 +692,8 @@ static void SuspendDevice(void)
OK_(crypt_suspend(cd, CDEVICE_1)); OK_(crypt_suspend(cd, CDEVICE_1));
FAIL_(crypt_resume_by_keyfile(cd, CDEVICE_1, CRYPT_ANY_SLOT, KEYFILE1 "blah", 0), "wrong keyfile"); FAIL_(crypt_resume_by_keyfile(cd, CDEVICE_1, CRYPT_ANY_SLOT, KEYFILE1 "blah", 0), "wrong keyfile");
FAIL_(crypt_resume_by_keyfile_offset(cd, CDEVICE_1, CRYPT_ANY_SLOT, KEYFILE1, 1, 0), "wrong key"); FAIL_(crypt_resume_by_keyfile_offset(cd, CDEVICE_1, CRYPT_ANY_SLOT, KEYFILE1, 1, 0), "wrong key");
OK_(crypt_resume_by_keyfile_offset(cd, CDEVICE_1, CRYPT_ANY_SLOT, KEYFILE1, 0, 0)); FAIL_(crypt_resume_by_keyfile_device_offset(cd, CDEVICE_1, CRYPT_ANY_SLOT, KEYFILE1, 1, 0), "wrong key");
OK_(crypt_resume_by_keyfile_device_offset(cd, CDEVICE_1, CRYPT_ANY_SLOT, KEYFILE1, 0, 0));
FAIL_(crypt_resume_by_keyfile(cd, CDEVICE_1, CRYPT_ANY_SLOT, KEYFILE1, 0), "not suspended"); FAIL_(crypt_resume_by_keyfile(cd, CDEVICE_1, CRYPT_ANY_SLOT, KEYFILE1, 0), "not suspended");
OK_(crypt_deactivate(cd, CDEVICE_1)); OK_(crypt_deactivate(cd, CDEVICE_1));
crypt_free(cd); crypt_free(cd);

View File

@@ -588,6 +588,15 @@ $CRYPTSETUP luksClose $DEV_NAME || fail
$CRYPTSETUP luksChangeKey $LOOPDEV $FAST_PBKDF_OPT -d $KEY2 --keyfile-offset 1 $KEY2 --new-keyfile-offset 0 || fail $CRYPTSETUP luksChangeKey $LOOPDEV $FAST_PBKDF_OPT -d $KEY2 --keyfile-offset 1 $KEY2 --new-keyfile-offset 0 || fail
$CRYPTSETUP luksOpen -d $KEY2 $LOOPDEV $DEV_NAME || fail $CRYPTSETUP luksOpen -d $KEY2 $LOOPDEV $DEV_NAME || fail
$CRYPTSETUP luksClose $DEV_NAME || fail $CRYPTSETUP luksClose $DEV_NAME || fail
# large device with keyfile
echo -e '0 10000000 error'\\n'10000000 1000000 zero' | dmsetup create $DEV_NAME2 || fail
$CRYPTSETUP -q luksFormat $FAST_PBKDF_OPT $LOOPDEV /dev/mapper/$DEV_NAME2 -l 13 --keyfile-offset 5120000000 || fail
$CRYPTSETUP --key-file=/dev/mapper/$DEV_NAME2 -l 13 --keyfile-offset 5119999999 luksOpen $LOOPDEV $DEV_NAME 2>/dev/null && fail
$CRYPTSETUP --key-file=/dev/mapper/$DEV_NAME2 -l 13 --keyfile-offset 5120000000 luksOpen $LOOPDEV $DEV_NAME || fail
$CRYPTSETUP luksClose $DEV_NAME || fail
$CRYPTSETUP luksChangeKey $LOOPDEV $FAST_PBKDF_OPT -d /dev/mapper/$DEV_NAME2 \
--keyfile-offset 5120000000 -l 13 /dev/mapper/$DEV_NAME2 --new-keyfile-offset 5120000001 --new-keyfile-size 15 || fail
dmsetup remove $DEV_NAME2
prepare "[25] Create shared segments" wipe prepare "[25] Create shared segments" wipe
echo $PWD1 | $CRYPTSETUP create $DEV_NAME $LOOPDEV --hash sha1 --offset 0 --size 256 || fail echo $PWD1 | $CRYPTSETUP create $DEV_NAME $LOOPDEV --hash sha1 --offset 0 --size 256 || fail