static char *opt_key_file = NULL;
static char *opt_master_key_file = NULL;
static char *opt_header_backup_file = NULL;
+static char *opt_uuid = NULL;
static unsigned int opt_key_size = 0;
+static unsigned int opt_keyfile_size = 0;
+static unsigned int opt_new_keyfile_size = 0;
static int opt_key_slot = CRYPT_ANY_SLOT;
static uint64_t opt_size = 0;
static uint64_t opt_offset = 0;
fd = open(file, O_RDONLY);
if (fd == -1) {
log_err("Cannot read keyfile %s.\n", file);
- return -EINVAL;
+ goto fail;
}
if ((read(fd, *key, keysize) != keysize)) {
log_err("Cannot read %d bytes from keyfile %s.\n", keysize, file);
close(fd);
- crypt_safe_free(*key);
- return -EINVAL;
+ goto fail;
}
close(fd);
return 0;
+fail:
+ crypt_safe_free(*key);
+ *key = NULL;
+ return -EINVAL;
}
static int action_luksFormat(int arg)
.data_alignment = opt_align_payload,
};
- /* Avoid overwriting possibly wrong part of device than user requested by rejecting these options */
- if (opt_offset || opt_skip) {
- log_err("Options --offset and --skip are not supported for luksFormat.\n");
- r = -EINVAL;
- goto out;;
- }
-
if (action_argc > 1) {
key_file = action_argv[1];
if (opt_key_file)
r = -ENOMEM;
goto out;
}
- r = yesDialog(msg);
+ r = yesDialog(msg) ? 0 : -EINVAL;
free(msg);
-
- if (!r) {
- r = -EINVAL;
+ if (r < 0)
goto out;
- }
r = crypt_parse_name_and_mode(opt_cipher ?: DEFAULT_CIPHER(LUKS1),
cipher, cipher_mode);
else if (opt_urandom)
crypt_set_rng_type(cd, CRYPT_RNG_URANDOM);
+ r = -EINVAL;
+ crypt_get_key(_("Enter LUKS passphrase: "),
+ &password, &passwordLen,
+ opt_keyfile_size, key_file,
+ opt_timeout,
+ opt_batch_mode ? 0 : 1, /* always verify */
+ cd);
+ if(!password)
+ goto out;
+
if (opt_master_key_file) {
r = _read_mk(opt_master_key_file, &key, keysize);
if (r < 0)
goto out;
+ }
- r = crypt_format(cd, CRYPT_LUKS1, cipher, cipher_mode,
- NULL, key, keysize, ¶ms);
- if (r < 0)
- goto out;
-
- r = crypt_keyslot_add_by_volume_key(cd, opt_key_slot,
- key, keysize, NULL, 0);
- } else {
- crypt_get_key(_("Enter LUKS passphrase: "),
- &password, &passwordLen, 0,
- key_file, opt_timeout,
- opt_verify_passphrase && !opt_batch_mode,
- cd);
-
- if(!password) {
- r = -EINVAL;
- goto out;
- }
-
- r = crypt_format(cd, CRYPT_LUKS1, cipher, cipher_mode,
- NULL, NULL, keysize, ¶ms);
- if (r < 0)
- goto out;
+ r = crypt_format(cd, CRYPT_LUKS1, cipher, cipher_mode,
+ opt_uuid, key, keysize, ¶ms);
+ if (r < 0)
+ goto out;
- /* Add keyslot using internally stored volume key generated during format */
- r = crypt_keyslot_add_by_volume_key(cd, opt_key_slot,
- NULL, 0, password, passwordLen);
- }
+ r = crypt_keyslot_add_by_volume_key(cd, opt_key_slot,
+ key, keysize,
+ password, passwordLen);
out:
crypt_free(cd);
crypt_safe_free(key);
if (opt_key_file) {
crypt_set_password_retry(cd, 1);
- /* limit bytes read from keyfile using opt_key_size*/
r = crypt_activate_by_keyfile(cd, action_argv[1],
- CRYPT_ANY_SLOT, opt_key_file, opt_key_size / 8,
+ CRYPT_ANY_SLOT, opt_key_file, opt_keyfile_size,
flags);
} else
r = crypt_activate_by_passphrase(cd, action_argv[1],
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, 0,
- opt_new_key_file, 0);
+ opt_key_file, opt_keyfile_size,
+ opt_new_key_file, opt_new_keyfile_size);
} else {
r = crypt_keyslot_add_by_passphrase(cd, opt_key_slot,
NULL, 0, NULL, 0);
static int action_luksUUID(int arg)
{
- struct crypt_options options = {
- .device = action_argv[0],
- .icb = &cmd_icb,
- };
+ struct crypt_device *cd = NULL;
+ const char *existing_uuid = NULL;
+ int r;
+
+ if ((r = crypt_init(&cd, action_argv[0])))
+ goto out;
+
+ crypt_set_log_callback(cd, _log, NULL);
+ crypt_set_confirm_callback(cd, _yesDialog, NULL);
+
+ if ((r = crypt_load(cd, CRYPT_LUKS1, NULL)))
+ goto out;
+
+ if (opt_uuid)
+ r = crypt_set_uuid(cd, opt_uuid);
+ else {
+ existing_uuid = crypt_get_uuid(cd);
+ log_std("%s\n", existing_uuid ?: "");
+ r = existing_uuid ? 0 : 1;
+ }
+out:
+ crypt_free(cd);
+ return r;
- return crypt_luksUUID(&options);
}
static int action_luksDump(int arg)
if (opt_key_file)
r = crypt_resume_by_keyfile(cd, action_argv[0], CRYPT_ANY_SLOT,
- opt_key_file, opt_key_size / 8);
+ opt_key_file, opt_keyfile_size);
else
r = crypt_resume_by_passphrase(cd, action_argv[0], CRYPT_ANY_SLOT,
NULL, 0);
{ "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 },
{ "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, 0, N_("Read the key from a file (can be /dev/random)"), NULL },
+ { "key-file", 'd', POPT_ARG_STRING, &opt_key_file, 0, 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 },
{ "key-size", 's', POPT_ARG_INT, &opt_key_size, 0, N_("The size of the encryption key"), N_("BITS") },
+ { "keyfile-size", 'l', POPT_ARG_INT, &opt_keyfile_size, 0, N_("Limits the read from keyfile"), N_("bytes") },
+ { "new-keyfile-size", '\0', POPT_ARG_INT, &opt_new_keyfile_size, 0, N_("Limits the read from 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") },
{ "header-backup-file",'\0', POPT_ARG_STRING, &opt_header_backup_file, 0, N_("File with LUKS header and keyslots backup."), NULL },
{ "use-random", '\0', POPT_ARG_NONE, &opt_random, 0, N_("Use /dev/random for generating volume key."), NULL },
{ "use-urandom", '\0', POPT_ARG_NONE, &opt_urandom, 0, N_("Use /dev/urandom for generating volume key."), NULL },
+ { "uuid", '\0', POPT_ARG_STRING, &opt_uuid, 0, N_("UUID for device to use."), NULL },
POPT_TABLEEND
};
poptContext popt_context;
exit(0);
}
+ if (!(aname = (char *)poptGetArg(popt_context)))
+ usage(popt_context, 1, _("Argument <action> missing."),
+ poptGetInvocationName(popt_context));
+ for(action = action_types; action->type; action++)
+ if (strcmp(action->type, aname) == 0)
+ break;
+ if (!action->type)
+ usage(popt_context, 1, _("Unknown action."),
+ poptGetInvocationName(popt_context));
+
+ if (opt_key_size &&
+ strcmp(aname, "luksFormat") &&
+ strcmp(aname, "create")) {
+ usage(popt_context, 1,
+ _("Option --key-size is allowed only for luksFormat and create.\n"
+ "To limit read from keyfile use --keyfile-size=(bytes)."),
+ poptGetInvocationName(popt_context));
+ }
+
if (opt_key_size % 8)
usage(popt_context, 1,
_("Key size must be a multiple of 8 bits"),
poptGetInvocationName(popt_context));
}
- if (!(aname = (char *)poptGetArg(popt_context)))
- usage(popt_context, 1, _("Argument <action> missing."),
- poptGetInvocationName(popt_context));
- for(action = action_types; action->type; action++)
- if (strcmp(action->type, aname) == 0)
- break;
- if (!action->type)
- usage(popt_context, 1, _("Unknown action."),
- poptGetInvocationName(popt_context));
-
if (opt_random && opt_urandom)
usage(popt_context, 1, _("Only one of --use-[u]random options is allowed."),
poptGetInvocationName(popt_context));
usage(popt_context, 1, _("Option --use-[u]random is allowed only for luksFormat."),
poptGetInvocationName(popt_context));
+ if (opt_uuid && strcmp(aname, "luksFormat") && strcmp(aname, "luksUUID"))
+ usage(popt_context, 1, _("Option --uuid is allowed only for luksFormat and luksUUID."),
+ poptGetInvocationName(popt_context));
+
+ if ((opt_offset || opt_skip) && strcmp(aname, "create"))
+ usage(popt_context, 1, _("Options --offset and --skip are supported only for create command.\n"),
+ poptGetInvocationName(popt_context));
+
action_argc = 0;
action_argv = poptGetArgs(popt_context);
/* Make return values of poptGetArgs more consistent in case of remaining argc = 0 */