Commit 9511c91a authored by Milan Broz's avatar Milan Broz

Add --keyfile-offset and --new-keyfile-offset to cryptsetup.

Add resume_by_keyfile_offset, add_kesylot_by_keyfile_offset and
activate_by_keyfile_offset to API.

Thanks to Matthew Monaco <matthew.monaco@0x01b.net>
parent 570b0ecd
2012-03-16 Milan Broz <gmazyland@gmail.com>
* Add --keyfile-offset and --new-keyfile-offset parameters to API and CLI.
2012-03-16 Milan Broz <mbroz@redhat.com>
* Unify password verification option.
* Support password verification with quiet flag if possible. (1.2.0)
......
......@@ -3,7 +3,7 @@ AC_INIT([cryptsetup],[1.4.1])
dnl library version from <major>.<minor>.<release>[-<suffix>]
LIBCRYPTSETUP_VERSION=$(echo $PACKAGE_VERSION | cut -f1 -d-)
LIBCRYPTSETUP_VERSION_INFO=4:0:0
LIBCRYPTSETUP_VERSION_INFO=5:0:1
AC_CONFIG_SRCDIR(src/cryptsetup.c)
AC_CONFIG_MACRO_DIR([m4])
......
......@@ -433,10 +433,10 @@ int crypt_suspend(struct crypt_device *cd,
* @note Only LUKS device type is supported
*/
int crypt_resume_by_passphrase(struct crypt_device *cd,
const char *name,
int keyslot,
const char *passphrase,
size_t passphrase_size);
const char *name,
int keyslot,
const char *passphrase,
size_t passphrase_size);
/**
* Resumes crypt device using key file.
......@@ -446,14 +446,24 @@ int crypt_resume_by_passphrase(struct crypt_device *cd,
* @param keyslot requested keyslot or CRYPT_ANY_SLOT
* @param keyfile key file used to unlock volume key, @e NULL for passphrase query
* @param keyfile_size number of bytes to read from keyfile, 0 is unlimited
* @param keyfile_offset number of bytes to skip at start of keyfile
*
* @return unlocked key slot number or negative errno otherwise.
*/
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);
/**
* Backward compatible crypt_resume_by_keyfile_offset() (without offset).
*/
int crypt_resume_by_keyfile(struct crypt_device *cd,
const char *name,
int keyslot,
const char *keyfile,
size_t keyfile_size);
const char *name,
int keyslot,
const char *keyfile,
size_t keyfile_size);
/**
* Releases crypt device context and used memory.
......@@ -512,14 +522,27 @@ int crypt_keyslot_max(const char *type);
* @param keyslot requested keyslot or @e CRYPT_ANY_SLOT
* @param keyfile key file used to unlock volume key, @e NULL for passphrase query
* @param keyfile_size number of bytes to read from keyfile, @e 0 is unlimited
* @param keyfile_offset number of bytes to skip at start of keyfile
* @param new_keyfile keyfile for new keyslot, @e NULL for passphrase query
* @param new_keyfile_size number of bytes to read from @e new_keyfile, @e 0 is unlimited
* @param new_keyfile_offset number of bytes to skip at start of new_keyfile
*
* @return allocated key slot number or negative errno otherwise.
*
* @note Note that @e keyfile can be "-" for STDIN
*
*/
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);
/**
* Backward compatible crypt_keyslot_add_by_keyfile_offset() (without offset).
*/
int crypt_keyslot_add_by_keyfile(struct crypt_device *cd,
int keyslot,
const char *keyfile,
......@@ -636,10 +659,21 @@ int crypt_activate_by_passphrase(struct crypt_device *cd,
* @param keyslot requested keyslot to check or CRYPT_ANY_SLOT
* @param keyfile key file used to unlock volume key
* @param keyfile_size number of bytes to read from keyfile, 0 is unlimited
* @param keyfile_offset number of bytes to skip at start of keyfile
* @param flags activation flags
*
* @return unlocked key slot number or negative errno otherwise.
*/
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);
/**
* Backward compatible crypt_activate_by_keyfile_offset() (without offset).
*/
int crypt_activate_by_keyfile(struct crypt_device *cd,
const char *name,
int keyslot,
......
......@@ -21,14 +21,17 @@ CRYPTSETUP_1.0 {
crypt_suspend;
crypt_resume_by_passphrase;
crypt_resume_by_keyfile;
crypt_resume_by_keyfile_offset;
crypt_free;
crypt_keyslot_add_by_passphrase;
crypt_keyslot_add_by_keyfile;
crypt_keyslot_add_by_keyfile_offset;
crypt_keyslot_add_by_volume_key;
crypt_keyslot_destroy;
crypt_activate_by_passphrase;
crypt_activate_by_keyfile;
crypt_activate_by_keyfile_offset;
crypt_activate_by_volume_key;
crypt_deactivate;
crypt_volume_key_get;
......
......@@ -358,7 +358,7 @@ static int key_from_terminal(struct crypt_device *cd, char *msg, char **key,
} else
*key_len = r;
} else
r = crypt_get_key(msg, key, key_len, 0, NULL, cd->timeout,
r = crypt_get_key(msg, key, key_len, 0, 0, NULL, cd->timeout,
(force_verify || cd->password_verify), cd);
out:
free(prompt);
......@@ -408,9 +408,10 @@ out:
static int key_from_file(struct crypt_device *cd, char *msg,
char **key, size_t *key_len,
const char *key_file, size_t key_size)
const char *key_file, size_t key_offset,
size_t key_size)
{
return crypt_get_key(msg, key, key_len, key_size, key_file,
return crypt_get_key(msg, key, key_len, key_offset, key_size, key_file,
cd->timeout, 0, cd);
}
......@@ -1214,11 +1215,12 @@ out:
return r < 0 ? r : keyslot;
}
int crypt_resume_by_keyfile(struct crypt_device *cd,
const char *name,
int keyslot,
const char *keyfile,
size_t keyfile_size)
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)
{
struct volume_key *vk = NULL;
char *passphrase_read = NULL;
......@@ -1246,7 +1248,8 @@ int crypt_resume_by_keyfile(struct crypt_device *cd,
return -EINVAL;
r = key_from_file(cd, _("Enter passphrase: "), &passphrase_read,
&passphrase_size_read, keyfile, keyfile_size);
&passphrase_size_read, keyfile, keyfile_offset,
keyfile_size);
if (r < 0)
goto out;
......@@ -1265,6 +1268,16 @@ out:
return r < 0 ? r : keyslot;
}
int crypt_resume_by_keyfile(struct crypt_device *cd,
const char *name,
int keyslot,
const char *keyfile,
size_t keyfile_size)
{
return crypt_resume_by_keyfile_offset(cd, name, keyslot,
keyfile, keyfile_size, 0);
}
// slot manipulation
int crypt_keyslot_add_by_passphrase(struct crypt_device *cd,
int keyslot, // -1 any
......@@ -1341,12 +1354,14 @@ out:
return r ?: keyslot;
}
int crypt_keyslot_add_by_keyfile(struct crypt_device *cd,
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_size,
size_t new_keyfile_offset)
{
struct volume_key *vk = NULL;
char *password = NULL; size_t passwordLen;
......@@ -1379,7 +1394,7 @@ int crypt_keyslot_add_by_keyfile(struct crypt_device *cd,
if (keyfile)
r = key_from_file(cd, _("Enter any passphrase: "),
&password, &passwordLen,
keyfile, keyfile_size);
keyfile, keyfile_offset, keyfile_size);
else
r = key_from_terminal(cd, _("Enter any passphrase: "),
&password, &passwordLen, 0);
......@@ -1396,7 +1411,7 @@ int crypt_keyslot_add_by_keyfile(struct crypt_device *cd,
if (new_keyfile)
r = key_from_file(cd, _("Enter new passphrase for key slot: "),
&new_password, &new_passwordLen, new_keyfile,
new_keyfile_size);
new_keyfile_offset, new_keyfile_size);
else
r = key_from_terminal(cd, _("Enter new passphrase for key slot: "),
&new_password, &new_passwordLen, 1);
......@@ -1412,6 +1427,18 @@ out:
return r < 0 ? r : keyslot;
}
int crypt_keyslot_add_by_keyfile(struct crypt_device *cd,
int keyslot,
const char *keyfile,
size_t keyfile_size,
const char *new_keyfile,
size_t new_keyfile_size)
{
return crypt_keyslot_add_by_keyfile_offset(cd, keyslot,
keyfile, keyfile_size, 0,
new_keyfile, new_keyfile_size, 0);
}
int crypt_keyslot_add_by_volume_key(struct crypt_device *cd,
int keyslot,
const char *volume_key,
......@@ -1562,11 +1589,12 @@ out:
return r < 0 ? r : keyslot;
}
int crypt_activate_by_keyfile(struct crypt_device *cd,
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)
{
crypt_status_info ci;
......@@ -1598,7 +1626,7 @@ int crypt_activate_by_keyfile(struct crypt_device *cd,
r = key_from_file(cd, _("Enter passphrase: "),
&passphrase_read, &passphrase_size_read,
keyfile, keyfile_size);
keyfile, keyfile_offset, keyfile_size);
if (r < 0)
goto out;
......@@ -1611,7 +1639,7 @@ int crypt_activate_by_keyfile(struct crypt_device *cd,
r = PLAIN_activate(cd, name, vk, cd->plain_hdr.size, flags);
} else if (isLUKS(cd->type)) {
r = key_from_file(cd, _("Enter passphrase: "), &passphrase_read,
&passphrase_size_read, keyfile, keyfile_size);
&passphrase_size_read, keyfile, keyfile_offset, keyfile_size);
if (r < 0)
goto out;
r = LUKS_open_key_with_hdr(mdata_device(cd), keyslot, passphrase_read,
......@@ -1628,7 +1656,7 @@ int crypt_activate_by_keyfile(struct crypt_device *cd,
r = keyslot;
} else if (isLOOPAES(cd->type)) {
r = key_from_file(cd, NULL, &passphrase_read, &passphrase_size_read,
keyfile, keyfile_size);
keyfile, keyfile_offset, keyfile_size);
if (r < 0)
goto out;
r = LOOPAES_parse_keyfile(cd, &vk, cd->loopaes_hdr.hash, &key_count,
......@@ -1648,6 +1676,17 @@ out:
return r;
}
int crypt_activate_by_keyfile(struct crypt_device *cd,
const char *name,
int keyslot,
const char *keyfile,
size_t keyfile_size,
uint32_t flags)
{
return crypt_activate_by_keyfile_offset(cd, name, keyslot, keyfile,
keyfile_size, 0, flags);
}
int crypt_activate_by_volume_key(struct crypt_device *cd,
const char *name,
const char *volume_key,
......
......@@ -257,14 +257,14 @@ out_err:
*/
int crypt_get_key(const char *prompt,
char **key, size_t *key_size,
size_t keyfile_size_max, const char *key_file,
int timeout, int verify,
size_t keyfile_offset, size_t keyfile_size_max,
const char *key_file, int timeout, int verify,
struct crypt_device *cd)
{
int fd, regular_file, read_stdin, char_read, unlimited_read = 0;
int r = -EINVAL;
char *pass = NULL;
size_t buflen, i;
char *pass = NULL, tmp;
size_t buflen, i, file_read_size;
struct stat st;
*key = NULL;
......@@ -273,8 +273,13 @@ int crypt_get_key(const char *prompt,
/* Passphrase read from stdin? */
read_stdin = (!key_file || !strcmp(key_file, "-")) ? 1 : 0;
if (read_stdin && isatty(STDIN_FILENO))
if (read_stdin && isatty(STDIN_FILENO)) {
if (keyfile_offset) {
log_err(cd, _("Cannot use offset with terminal input.\n"));
return -EINVAL;
}
return crypt_get_key_tty(prompt, key, key_size, timeout, verify, cd);
}
if (read_stdin)
log_dbg("STDIN descriptor passphrase entry requested.");
......@@ -303,11 +308,19 @@ int crypt_get_key(const char *prompt,
}
if(S_ISREG(st.st_mode)) {
regular_file = 1;
file_read_size = (size_t)st.st_size;
if (keyfile_offset > file_read_size) {
log_err(cd, _("Cannot seek to requested keyfile offset.\n"));
goto out_err;
}
file_read_size -= keyfile_offset;
/* known keyfile size, alloc it in one step */
if ((size_t)st.st_size >= keyfile_size_max)
if (file_read_size >= keyfile_size_max)
buflen = keyfile_size_max;
else if (st.st_size)
buflen = st.st_size;
else if (file_read_size)
buflen = file_read_size;
}
}
......@@ -317,6 +330,13 @@ int crypt_get_key(const char *prompt,
goto out_err;
}
/* Discard keyfile_offset bytes on input */
for(i = 0; i < keyfile_offset; i++)
if (read(fd, &tmp, 1) != 1) {
log_err(cd, _("Cannot seek to requested keyfile offset.\n"));
goto out_err;
}
for(i = 0; i < keyfile_size_max; i++) {
if(i == buflen) {
buflen += 4096;
......
......@@ -14,7 +14,7 @@ int crypt_parse_name_and_mode(const char *s, char *cipher,
int crypt_get_key(const char *prompt,
char **key, size_t *key_size,
size_t keyfile_size_max,
size_t keyfile_offset, size_t keyfile_size_max,
const char *key_file,
int timeout, int verify,
struct crypt_device *cd);
......
......@@ -14,8 +14,8 @@ For basic (plain) dm-crypt mappings, there are four operations.
creates a mapping with <name> backed by device <device>.
\fB<options>\fR can be [\-\-hash, \-\-cipher, \-\-verify-passphrase,
\-\-key-file, \-\-key-size, \-\-offset, \-\-skip, \-\-size, \-\-readonly, \-\-shared,
\-\-allow-discards]
\-\-key-file, \-\-keyfile-offset, \-\-key-size, \-\-offset, \-\-skip, \-\-size,
\-\-readonly, \-\-shared, \-\-allow-discards]
.PP
\fIremove\fR <name>
.IP
......@@ -51,7 +51,8 @@ initializes a LUKS partition and sets the initial key, either via prompting or v
\fB<options>\fR can be [\-\-cipher, \-\-verify-passphrase, \-\-key-size,
\-\-key-slot, \-\-key-file (takes precedence over optional second argument),
\-\-keyfile-size, \-\-use-random | \-\-use-urandom, \-\-uuid, \-\-master-key-file].
\-\-keyfile-offset, \-\-keyfile-size, \-\-use-random | \-\-use-urandom, \-\-uuid,
\-\-master-key-file].
.PP
\fIluksOpen\fR <device> <name>
.IP
......@@ -62,8 +63,8 @@ successful verification of the supplied key material
Device parameter can be also specified by LUKS UUID in the format UUID=<uuid>
(then cryptsetup will use /dev/disk/by-uuid symlinks).
\fB<options>\fR can be [\-\-key-file, \-\-keyfile-size, \-\-readonly, \-\-allow-discards,
\-\-header, \-\-key-slot, \-\-master-key-file].
\fB<options>\fR can be [\-\-key-file, \-\-keyfile-offset, \-\-keyfile-size, \-\-readonly,
\-\-allow-discards, \-\-header, \-\-key-slot, \-\-master-key-file].
.PP
\fIluksClose\fR <name>
.IP
......@@ -94,8 +95,8 @@ add a new key file/passphrase. An existing passphrase or key file
(via \-\-key-file) must be supplied.
The key file with the new material is supplied as a positional argument.
\fB<options>\fR can be [\-\-key-file, \-\-keyfile-size, \-\-new-keyfile-size, \-\-key-slot,
\-\-master-key-file].
\fB<options>\fR can be [\-\-key-file, \-\-keyfile-offset, \-\-keyfile-size, \-\-new-keyfile-offset,
\-\-new-keyfile-size, \-\-key-slot, \-\-master-key-file].
.PP
\fIluksRemoveKey\fR <device> [<key file>]
.IP
......@@ -117,15 +118,15 @@ command will overwrite existing slot.
when using explicit key slot (so you can unlock the device even after
possible media failure during slot swap).
\fB<options>\fR can be [\-\-key-file, \-\-keyfile-size,\-\-new-keyfile-size,
\-\-key-slot].
\fB<options>\fR can be [\-\-key-file, \-\-keyfile-offset, \-\-keyfile-size, \-\-new-keyfile-offset,
\-\-new-keyfile-size, \-\-key-slot].
.PP
\fIluksKillSlot\fR <device> <key slot number>
.IP
wipe key with number <key slot> from LUKS device. A remaining passphrase or
key file (via \-\-key-file) must be supplied.
\fB<options>\fR can be [\-\-key-file, \-\-keyfile-size].
\fB<options>\fR can be [\-\-key-file, \-\-keyfile-offset, \-\-keyfile-size].
.PP
\fIluksUUID\fR <device>
.IP
......@@ -153,7 +154,7 @@ stored encrypted and on safe place.
LUKS passphrase or key file is required for volume key dump.
\fB<options>\fR can be [\-\-dump-master-key, \-\-key-file, \-\-keyfile-size].
\fB<options>\fR can be [\-\-dump-master-key, \-\-key-file, \-\-keyfile-offset, \-\-keyfile-size].
.PP
\fIluksHeaderBackup\fR <device> \-\-header-backup-file <file>
.IP
......@@ -269,10 +270,18 @@ reading will not stop when new line character is detected.
See section \fBNOTES ON PASSWORD PROCESSING\fR for more information.
.TP
.B "\-\-keyfile-offset \fIvalue\fR"
Begins read from key file at \fIvalue\fR bytes.
Usable together with all commands using key file.
.TP
.B "\-\-keyfile-size, \-l \fIvalue\fR"
Limits read from key file to \fIvalue\fR bytes.
Usable together with all commands using key file.
.TP
.B "\-\-new-keyfile-offset \fIvalue\fR"
Begins read from new key file at \fIvalue\fR bytes in \fIluksAddKey\fR when
adding new key file. Default is to start at the beginning of key file.
.TP
.B "\-\-new-keyfile-size \fIvalue\fR"
Limits read from new key file to \fIvalue\fR bytes in \fIluksAddKey\fR when
adding new key file. Default is exhaustive read from key file.
......
......@@ -50,6 +50,8 @@ static const char *opt_header_device = NULL;
static int opt_key_size = 0;
static long opt_keyfile_size = 0;
static long opt_new_keyfile_size = 0;
static long opt_keyfile_offset = 0;
static long opt_new_keyfile_offset = 0;
static int opt_key_slot = CRYPT_ANY_SLOT;
static uint64_t opt_size = 0;
static uint64_t opt_offset = 0;
......@@ -295,9 +297,9 @@ static int action_create(int arg __attribute__((unused)))
if (opt_key_file && strcmp(opt_key_file, "-"))
params.hash = NULL;
if (opt_keyfile_size && opt_key_file)
log_std(("Ignoring keyfile size option, keyfile read size "
"is always the same as encryption key size.\n"));
if ((opt_keyfile_offset || opt_keyfile_size) && opt_key_file)
log_std(("Ignoring keyfile offset and size options, keyfile read "
"size is always the same as encryption key size.\n"));
r = crypt_parse_name_and_mode(opt_cipher ?: DEFAULT_CIPHER(PLAIN),
cipher, NULL, cipher_mode);
......@@ -331,12 +333,14 @@ static int action_create(int arg __attribute__((unused)))
if (opt_key_file)
/* With hashing, read the whole keyfile */
r = crypt_activate_by_keyfile(cd, action_argv[0],
CRYPT_ANY_SLOT, opt_key_file, params.hash ? 0 : key_size,
r = crypt_activate_by_keyfile_offset(cd, action_argv[0],
CRYPT_ANY_SLOT, opt_key_file,
params.hash ? 0 : key_size, 0,
activate_flags);
else {
r = crypt_get_key(_("Enter passphrase: "),
&password, &passwordLen, opt_keyfile_size,
&password, &passwordLen,
opt_keyfile_offset, opt_keyfile_size,
NULL, opt_timeout,
_verify_passphrase(0),
cd);
......@@ -384,8 +388,9 @@ static int action_loopaesOpen(int arg __attribute__((unused)))
if (r < 0)
goto out;
r = crypt_activate_by_keyfile(cd, action_argv[1], CRYPT_ANY_SLOT,
opt_key_file, opt_keyfile_size, activate_flags);
r = crypt_activate_by_keyfile_offset(cd, action_argv[1], CRYPT_ANY_SLOT,
opt_key_file, opt_keyfile_size,
opt_keyfile_size, activate_flags);
out:
crypt_free(cd);
......@@ -564,8 +569,8 @@ static int action_luksFormat(int arg __attribute__((unused)))
crypt_set_rng_type(cd, CRYPT_RNG_URANDOM);
r = crypt_get_key(_("Enter LUKS passphrase: "), &password, &passwordLen,
opt_keyfile_size, opt_key_file, opt_timeout,
_verify_passphrase(1), cd);
opt_keyfile_offset, opt_keyfile_size, opt_key_file,
opt_timeout, _verify_passphrase(1), cd);
if (r < 0)
goto out;
......@@ -645,9 +650,9 @@ static int action_luksOpen(int arg __attribute__((unused)))
key, keysize, flags);
} else if (opt_key_file) {
crypt_set_password_retry(cd, 1);
r = crypt_activate_by_keyfile(cd, action_argv[1],
r = crypt_activate_by_keyfile_offset(cd, action_argv[1],
opt_key_slot, opt_key_file, opt_keyfile_size,
flags);
opt_keyfile_offset, flags);
} else
r = crypt_activate_by_passphrase(cd, action_argv[1],
opt_key_slot, NULL, 0, flags);
......@@ -659,7 +664,8 @@ out:
static int verify_keyslot(struct crypt_device *cd, int key_slot,
char *msg_last, char *msg_pass,
const char *key_file, int keyfile_size)
const char *key_file, int keyfile_offset,
int keyfile_size)
{
crypt_keyslot_info ki;
char *password = NULL;
......@@ -671,7 +677,7 @@ static int verify_keyslot(struct crypt_device *cd, int key_slot,
return -EPERM;
r = crypt_get_key(msg_pass, &password, &passwordLen,
keyfile_size, key_file, opt_timeout,
keyfile_offset, keyfile_size, key_file, opt_timeout,
_verify_passphrase(0), cd);
if(r < 0)
goto out;
......@@ -731,7 +737,7 @@ static int action_luksKillSlot(int arg __attribute__((unused)))
r = verify_keyslot(cd, opt_key_slot,
_("This is the last keyslot. Device will become unusable after purging this key."),
_("Enter any remaining LUKS passphrase: "),
opt_key_file, opt_keyfile_size);
opt_key_file, opt_keyfile_offset, opt_keyfile_size);
if (r < 0)
goto out;
}
......@@ -760,7 +766,7 @@ static int action_luksRemoveKey(int arg __attribute__((unused)))
r = crypt_get_key(_("Enter LUKS passphrase to be deleted: "),
&password, &passwordLen,
opt_keyfile_size, opt_key_file,
opt_keyfile_offset, opt_keyfile_size, opt_key_file,
opt_timeout,
_verify_passphrase(0),
cd);
......@@ -820,9 +826,9 @@ static int action_luksAddKey(int arg __attribute__((unused)))
r = crypt_keyslot_add_by_volume_key(cd, opt_key_slot,
key, keysize, NULL, 0);
} else if (opt_key_file || opt_new_key_file) {
r = crypt_keyslot_add_by_keyfile(cd, opt_key_slot,
opt_key_file, opt_keyfile_size,
opt_new_key_file, opt_new_keyfile_size);
r = crypt_keyslot_add_by_keyfile_offset(cd, opt_key_slot,
opt_key_file, opt_keyfile_size, opt_keyfile_offset,
opt_new_key_file, opt_new_keyfile_size, opt_new_keyfile_offset);
} else {
r = crypt_keyslot_add_by_passphrase(cd, opt_key_slot,
NULL, 0, NULL, 0);
......@@ -863,8 +869,8 @@ static int action_luksChangeKey(int arg __attribute__((unused)))
r = crypt_get_key(_("Enter LUKS passphrase to be changed: "),
&password, &passwordLen,
opt_keyfile_size, opt_key_file, opt_timeout,
_verify_passphrase(0), cd);
opt_keyfile_offset, opt_keyfile_size, opt_key_file,
opt_timeout, _verify_passphrase(0), cd);
if (r < 0)
goto out;
......@@ -900,7 +906,8 @@ static int action_luksChangeKey(int arg __attribute__((unused)))
passwordLen = 0;
r = crypt_get_key(_("Enter new LUKS passphrase: "),
&password, &passwordLen,
opt_new_keyfile_size, opt_new_key_file,
opt_new_keyfile_offset, opt_new_keyfile_size,
opt_new_key_file,
opt_timeout, _verify_passphrase(0), cd);
if (r < 0)
goto out;
......@@ -993,7 +1000,8 @@ static int luksDump_with_volume_key(struct crypt_device *cd)
return -ENOMEM;
r = crypt_get_key(_("Enter LUKS passphrase: "), &password, &passwordLen,
opt_keyfile_size, opt_key_file, opt_timeout, 0, cd);
opt_keyfile_offset, opt_keyfile_size, opt_key_file,
opt_timeout, 0, cd);
if (r < 0)
goto out;
......@@ -1069,8 +1077,8 @@ static int action_luksResume(int arg __attribute__((unused)))
crypt_set_password_verify(cd, _verify_passphrase(0));
if (opt_key_file)
r = crypt_resume_by_keyfile(cd, action_argv[0], CRYPT_ANY_SLOT,
opt_key_file, opt_keyfile_size);
r = crypt_resume_by_keyfile_offset(cd, action_argv[0], CRYPT_ANY_SLOT,
opt_key_file, opt_keyfile_size, opt_keyfile_offset);
else
r = crypt_resume_by_passphrase(cd, action_argv[0], CRYPT_ANY_SLOT,
NULL, 0);
......@@ -1247,7 +1255,9 @@ int main(int argc, const char **argv)
{ "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") },
{ "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") },
{ "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") },
{ "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") },
{ "offset", 'o', POPT_ARG_STRING, &popt_tmp, 2, N_("The start offset in the backend device"), N_("SECTORS") },
......@@ -1395,7 +1405,8 @@ int main(int argc, const char **argv)
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,
_("Negative number for option not permitted."),
poptGetInvocationName(popt_context));
......
......@@ -469,9 +469,10 @@ static void check_ko(int status, int line, const char *func)
printf(" => errno %d, errmsg: %s\n", status, buf);
}
static void check_equal(int line, const char *func)
static void check_equal(int line, const char *func, int64_t x, int64_t y)
{
printf("FAIL line %d [%s]: expected equal values differs.\n", line, func);
printf("FAIL line %d [%s]: expected equal values differs: %"
PRIi64 " != %" PRIi64 "\n", line, func, x, y);
_cleanup();
exit(-1);
}
......@@ -494,9 +495,9 @@ static void xlog(const char *msg, const char *tst, const char *func, int line, c
check_ko((x), __LINE__, __FUNCTION__); \
} while(0)
#define EQ_(x, y) do { xlog("(equal) ", #x " == " #y, __FUNCTION__, __LINE__, NULL); \
if ((x) != (y)) check_equal(__LINE__, __FUNCTION__); \
int64_t _x = (x), _y = (y); \
if (_x != _y) check_equal(__LINE__, __FUNCTION__, _x, _y); \
} while(0)
#define RUN_(x, y) do { printf("%s: %s\n", #x, (y)); x(); } while (0)
static void AddDevicePlain(void)
......@@ -769,6 +770,9 @@ static void AddDevicePlain(void)
EQ_(0, crypt_activate_by_keyfile(cd, CDEVICE_1, CRYPT_ANY_SLOT, KEYFILE1, 0, 0));
EQ_(crypt_status(cd, CDEVICE_1), CRYPT_ACTIVE);
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");
EQ_(0, crypt_activate_by_keyfile_offset(cd, CDEVICE_1, CRYPT_ANY_SLOT, KEYFILE1, 0, 0, 0));
OK_(crypt_deactivate(cd, CDEVICE_1));
_remove_keyfiles();
crypt_free(cd);
......@@ -921,7 +925,8 @@ static void SuspendDevice(void)
OK_(_prepare_keyfile(KEYFILE1, KEY1, strlen(KEY1)));
OK_(crypt_suspend(cd, CDEVICE_1));
FAIL_(crypt_resume_by_keyfile(cd, CDEVICE_1, CRYPT_ANY_SLOT, KEYFILE1 "blah", 0), "wrong keyfile");
OK_(crypt_resume_by_keyfile(cd, CDEVICE_1, CRYPT_ANY_SLOT, KEYFILE1, 0));
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(cd, CDEVICE_1, CRYPT_ANY_SLOT, KEYFILE1, 0), "not suspended");
_remove_keyfiles();
out:
......@@ -1046,7 +1051,7 @@ static void AddDeviceLuks(void)
// there we've got uuid mismatch
OK_(crypt_init_by_name_and_header(&cd, CDEVICE_1, DMDIR H_DEVICE));
EQ_(crypt_status(cd, CDEVICE_1), CRYPT_ACTIVE);
EQ_(crypt_get_type(cd), NULL);
OK_((int)crypt_get_type(cd));
FAIL_(crypt_activate_by_volume_key(cd, CDEVICE_1, key, key_size, 0), "Device is active");
FAIL_(crypt_activate_by_volume_key(cd, CDEVICE_2, key, key_size, 0), "Device is active");
EQ_(crypt_status(cd, CDEVICE_2), CRYPT_INACTIVE);
......@@ -1071,15 +1076,26 @@ static void AddDeviceLuks(void)
EQ_(crypt_status(cd, CDEVICE_2), CRYPT_ACTIVE);
OK_(crypt_deactivate(cd, CDEVICE_2));
crypt_set_iteration_time(cd, 1);
EQ_(1, crypt_keyslot_add_by_volume_key(cd, 1, key, key_size, KEY1, strlen(KEY1)));
OK_(_prepare_keyfile(KEYFILE1, KEY1, strlen(KEY1)));
OK_(_prepare_keyfile(KEYFILE2, KEY2, strlen(KEY2)));
EQ_(2, crypt_keyslot_add_by_keyfile(cd, 2, KEYFILE1, 0, KEYFILE2, 0));
FAIL_(crypt_keyslot_add_by_keyfile_offset(cd, 3, KEYFILE1, 0, 1, KEYFILE2, 0, 1), "wrong key");
EQ_(3, crypt_keyslot_add_by_keyfile_offset(cd, 3, KEYFILE1, 0, 0, KEYFILE2, 0, 1));
EQ_(4, crypt_keyslot_add_by_keyfile_offset(cd, 4, KEYFILE2, 0, 1, KEYFILE1, 0, 1));
FAIL_(crypt_activate_by_keyfile(cd, CDEVICE_2, CRYPT_ANY_SLOT, KEYFILE2, strlen(KEY2)-1, 0), "key mismatch");
EQ_(2, crypt_activate_by_keyfile(cd, NULL, CRYPT_ANY_SLOT, KEYFILE2, 0, 0));
EQ_(3, crypt_activate_by_keyfile_offset(cd, NULL, CRYPT_ANY_SLOT, KEYFILE2, 0, 1, 0));
EQ_(4, crypt_activate_by_keyfile_offset(cd, NULL, CRYPT_ANY_SLOT, KEYFILE1, 0, 1, 0));
FAIL_(crypt_activate_by_keyfile_offset(cd, CDEVICE_2, CRYPT_ANY_SLOT, KEYFILE2, strlen(KEY2), 2, 0), "not enough data");
FAIL_(crypt_activate_by_keyfile_offset(cd, CDEVICE_2, CRYPT_ANY_SLOT, KEYFILE2, 0, strlen(KEY2) + 1, 0), "cannot seek");
FAIL_(crypt_activate_by_keyfile_offset(cd, CDEVICE_2, CRYPT_ANY_SLOT, KEYFILE2, 0, 2, 0), "wrong key");
EQ_(2, crypt_activate_by_keyfile(cd, CDEVICE_2, CRYPT_ANY_SLOT, KEYFILE2, 0, 0));
OK_(crypt_keyslot_destroy(cd, 1));
OK_(crypt_keyslot_destroy(cd, 2));
OK_(crypt_keyslot_destroy(cd, 3));
OK_(crypt_keyslot_destroy(cd, 4));
OK_(crypt_deactivate(cd, CDEVICE_2));
_remove_keyfiles();
......@@ -1309,7 +1325,7 @@ static void LuksHeaderLoad(void)
// bad header: device too small (payloadOffset > device_size)
OK_(crypt_init(&cd, DMDIR H_DEVICE_WRONG));
FAIL_(crypt_load(cd, CRYPT_LUKS1, NULL), "Device too small");
EQ_(crypt_get_type(cd), NULL);
OK_((int)crypt_get_type(cd));
crypt_free(cd);
// 0 secs for encrypted data area
......